Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57567 - in sandbox/filesystem-v3: boost/filesystem libs/filesystem/doc libs/filesystem/example libs/filesystem/test
From: bdawes_at_[hidden]
Date: 2009-11-11 10:08:15


Author: bemandawes
Date: 2009-11-11 10:08:14 EST (Wed, 11 Nov 2009)
New Revision: 57567
URL: http://svn.boost.org/trac/boost/changeset/57567

Log:
More work on docs, refactoring of operations_test.cpp
Text files modified:
   sandbox/filesystem-v3/boost/filesystem/operations.hpp | 9
   sandbox/filesystem-v3/libs/filesystem/doc/reference.html | 65 ++-
   sandbox/filesystem-v3/libs/filesystem/example/error_demo.cpp | 16 +
   sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp | 599 +++++++++++++++++++++------------------
   4 files changed, 386 insertions(+), 303 deletions(-)

Modified: sandbox/filesystem-v3/boost/filesystem/operations.hpp
==============================================================================
--- sandbox/filesystem-v3/boost/filesystem/operations.hpp (original)
+++ sandbox/filesystem-v3/boost/filesystem/operations.hpp 2009-11-11 10:08:14 EST (Wed, 11 Nov 2009)
@@ -16,12 +16,10 @@
 *
 * Review all operations.cpp code for race conditions similar to #2925. Fix or document.
 * Enable all BOOST_FILESYSTEM_NO_DEPRECATED code.
-* Vista symlink_status support.
 * rename and remove really need to be renamed. If users says "using namespace boost::filesystem"
    and some header included stdio, there is just too much chance of silent error.
 * create_directories error handling.
 * Review any commented out code, both in operations.hpp and operations.cpp
-* Finish refactoring operations_test.
 * Fold convenience.hpp into operations.hpp
 * Two argument recursive_directory_iterator ctor isn't recognizing throws().
    would it be better to fold into a single two argument ctor with default?
@@ -584,10 +582,9 @@
 //--------------------------------------------------------------------------------------//
 
   class directory_iterator
- : public boost::iterator_facade<
- directory_iterator,
- directory_entry,
- boost::single_pass_traversal_tag >
+ : public boost::iterator_facade< directory_iterator,
+ directory_entry,
+ boost::single_pass_traversal_tag >
   {
   public:
 

Modified: sandbox/filesystem-v3/libs/filesystem/doc/reference.html
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/doc/reference.html (original)
+++ sandbox/filesystem-v3/libs/filesystem/doc/reference.html 2009-11-11 10:08:14 EST (Wed, 11 Nov 2009)
@@ -77,7 +77,7 @@
 &nbsp;&nbsp;&nbsp;
 <a href="#directory_iterator-constructors">directory_iterator
     constructors</a><br>
-Class recursive_directory_iterator<br>
+Class recursive_directory_iterator<br>
     <a href="#file_status">Class
     file_status</a><br>
     &nbsp;</td>
@@ -232,7 +232,7 @@
 
 </span> class directory_iterator;
 
- class recursive_directory_iterator;
+ class recursive_directory_iterator;
 
       enum <a name="file_type">file_type</a> { status_error, file_not_found, regular_file, directory_file,
                        symlink_file, block_file, character_file, fifo_file, socket_file,
@@ -346,21 +346,26 @@
     } // namespace filesystem
   } // namespace boost</pre>
 <h4><a name="Error-reporting">Error reporting</a></h4>
-<p>Use cases for the Filesystem library include situations where:</p>
+<p>Filesystem library functions often provide two overloads, one that
+throws an exception to report file system errors, and another that sets an
+<code>error_code</code>.</p>
+<blockquote>
+<p>[<i>Note:</i> This supports two common use cases:</p>
 <ul>
- <li>File system
+ <li>Uses where file system
 errors are truly exceptional and indicate a serious failure. Throwing an
- exception is the most appropriate response.<br>
+ exception is the most appropriate response. This is the preferred default for
+ most everyday programming.<br>
 &nbsp;</li>
- <li>File system system errors are routine and do not necessarily represent
- failure. Returning an error code is the most appropriate response.</li>
+ <li>Uses where file system system errors are routine and do not necessarily represent
+ failure. Returning an error code is the most appropriate response. This allows
+ application specific error handling, including simply ignoring the error.</li>
 </ul>
-<p>To support both uses cases, many filesystem library functions provide two overloads, one that
-throws an exception to report file system errors, and another that sets an
-<code>error_code</code>.</p>
-<p>Functions not having an argument of type
-<code>system::error_code&amp;</code>, unless otherwise specified,
-report errors as follows:</p>
+ <p><i>--end note</i>]</p>
+</blockquote>
+<p>Functions <b>not</b> having an argument of type
+<code>system::error_code&amp;</code>
+report errors as follows, unless otherwise specified:</p>
   <ul>
   <li>When a call by the
   implementation to an operating system or other underlying API results in an
@@ -369,10 +374,13 @@
 <code>filesystem_error</code> is thrown.<br>
 &nbsp;</li>
   <li>Failure to allocate storage is reported by throwing an exception as described in the C++ standard,
- 17.6.4.10 [res.on.exception.handling].</li>
+ 17.6.4.10 [res.on.exception.handling].<br>
+&nbsp;</li>
+ <li>Destructors throw nothing.</li>
   </ul>
   <p>Functions having an argument of type
-<code>system::error_code&amp;</code>, unless otherwise specified, report errors as follows:</p>
+<code>system::error_code&amp;</code> report errors as follows, unless otherwise
+ specified:</p>
 <ul>
   <li>If a call by the
   implementation to an operating system or other underlying API results in an
@@ -1575,6 +1583,9 @@
   m_symlink_status</code></span></p>
 </blockquote>
 <h3><a name="Class-directory_iterator">Class <code>directory_iterator</code></a></h3>
+<p>Objects of type <code>directory_iterator</code> provide standard library
+compliant iteration over the contents of a directory. Also see class <code>
+recursive_directory_iterator</code>.</p>
 <pre> namespace boost
   {
     namespace filesystem
@@ -1589,7 +1600,8 @@
 
         // constructors
         directory_iterator(); // creates the &quot;end&quot; iterator
- explicit directory_iterator(const path&amp; p, system::error_code&amp; ec);
+ explicit directory_iterator(const path&amp; p);
+ directory_iterator(const path&amp; p, system::error_code&amp; ec);
 
        ~directory_iterator();
 
@@ -1620,8 +1632,7 @@
 legitimate iterator to be used for the end condition. The result of <code>
 operator*</code> on an end iterator is not defined. For any other iterator value
 a <code>const directory_entry&amp;</code> is returned. The result of
-<code>operator-&gt;</code> on an end iterator is not defined. For any other
-iterator value a <code>const directory_entry*</code> is
+<code>operator-&gt;</code> on an end iterator is not defined. For any other iterator value a <code>const directory_entry*</code> is
 returned. </p>
 <p>Two end iterators are always equal. An end iterator is not equal to a non-end
 iterator.</p>
@@ -1664,19 +1675,29 @@
 
 <p><i>Effects:</i> Constructs the end iterator.</p>
 
+<p><i>Throws:</i> Nothing.</p>
+
 </blockquote>
 
-<pre><code>explicit directory_iterator(</code>const path&amp; p, system::error_code&amp; ec<code>);</code></pre>
+<pre><code>explicit directory_iterator(</code>const path&amp; p<code>);
+directory_iterator(</code>const path&amp; p, system::error_code&amp; ec<code>);</code></pre>
 <blockquote>
 
 <p><i>Effects:</i> Constructs a iterator representing the first
-entry in the directory resolved to by <code>dp</code>, otherwise, the end iterator.</p>
+entry in the directory <code>p</code> resolves to, if any, otherwise, the end iterator.</p>
+
+<p><i>Throws:</i> As specified in
+ <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
+ Error reporting</a>.</p>
 
 <p>[<i>Note:</i> To iterate over the current directory, write <code>
 directory_iterator(&quot;.&quot;)</code> rather than <code>directory_iterator(&quot;&quot;)</code>.
 <i>-- end note</i>]</p>
 </blockquote>
-<h3><a name="Class-template-recursive_directory_iterator">Class <code>recursive_directory_iterator</code></a></h3>
+<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
+compliant iteration over the contents of a directory, including recursion into
+its sub-directories.</p>
 <pre> namespace boost
   {
     namespace filesystem
@@ -3138,7 +3159,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 -->04 November 2009<!--webbot bot="Timestamp" endspan i-checksum="40588" --></p>
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->11 November 2009<!--webbot bot="Timestamp" endspan i-checksum="40583" --></p>
 
 </body>
 

Modified: sandbox/filesystem-v3/libs/filesystem/example/error_demo.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/example/error_demo.cpp (original)
+++ sandbox/filesystem-v3/libs/filesystem/example/error_demo.cpp 2009-11-11 10:08:14 EST (Wed, 11 Nov 2009)
@@ -74,6 +74,15 @@
     }
   }
 
+ void report_error_code(const error_code& ec)
+ {
+ cout << " ec:\n"
+ << " value() is " << ec.value() << '\n'
+ << " category().name() is " << ec.category().name() << '\n'
+ << " message() is " << ec.message() << '\n'
+ ;
+ }
+
   bool threw_exception;
 
 }
@@ -86,6 +95,8 @@
     return 1;
   }
 
+ error_code ec;
+
   // construct path - no error_code
 
   try { path p1(argv[1]); }
@@ -119,6 +130,11 @@
 
   // get status - with error_code
 
+ cout << "status(argv[1], ec);\n";
+ s = fs::status(p, ec);
+ report_status(s);
+ report_error_code(ec);
+
   // query existence - no error_code
 
   // query existence - with error_code

Modified: sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp (original)
+++ sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp 2009-11-11 10:08:14 EST (Wed, 11 Nov 2009)
@@ -261,7 +261,24 @@
     }
     BOOST_TEST(exception_thrown);
 
- std::cout << " exception_test cleanup" << std::endl;
+ // the bound functions should throw, so CHECK_EXCEPTION() should return true
+
+ BOOST_TEST(CHECK_EXCEPTION(bad_file_size, ENOENT));
+
+ if (platform == "Windows")
+ BOOST_TEST(CHECK_EXCEPTION(bad_directory_size, ENOENT));
+ else
+ BOOST_TEST(CHECK_EXCEPTION(bad_directory_size, 0));
+
+ // test path::exception members
+ try { fs::file_size(ng); } // will throw
+
+ catch (const fs::filesystem_error & ex)
+ {
+ BOOST_TEST(ex.path1().string() == " no-way, Jose");
+ }
+
+ std::cout << " exception_tests complete" << std::endl;
   }
   
   // directory_iterator_tests --------------------------------------------------------//
@@ -498,7 +515,7 @@
        
           // since create_symlink worked, copy_symlink should also work
       fs::path symlink2_ph(dir / "symlink2");
- fs::copy_symlink(from_ph, symlink2_ph);
+ fs::copy_symlink(from_ph, symlink2_ph);
       stat = fs::symlink_status(symlink2_ph);
       BOOST_TEST(fs::is_symlink(stat));
       BOOST_TEST(fs::exists(stat));
@@ -830,6 +847,297 @@
     BOOST_TEST(ec.category() == system_category);
   }
 
+ // remove_tests --------------------------------------------------------------------//
+
+ void remove_tests(const fs::path& dir)
+ {
+ std::cout << "remove_tests..." << std::endl;
+
+ // remove() file
+ fs::path file_ph = dir / "shortlife";
+ BOOST_TEST(!fs::exists(file_ph));
+ create_file(file_ph, "");
+ BOOST_TEST(fs::exists(file_ph));
+ BOOST_TEST(!fs::is_directory(file_ph));
+ BOOST_TEST(fs::remove(file_ph));
+ BOOST_TEST(!fs::exists(file_ph));
+ BOOST_TEST(!fs::remove("no-such-file"));
+ BOOST_TEST(!fs::remove("no-such-directory/no-such-file"));
+
+ // remove() directory
+ fs::path d1 = dir / "shortlife_dir";
+ BOOST_TEST(!fs::exists(d1));
+ fs::create_directory(d1);
+ BOOST_TEST(fs::exists(d1));
+ BOOST_TEST(fs::is_directory(d1));
+ BOOST_TEST(fs::is_empty(d1));
+ bad_remove_dir = dir;
+ BOOST_TEST(CHECK_EXCEPTION(bad_remove, ENOTEMPTY));
+ BOOST_TEST(fs::remove(d1));
+ BOOST_TEST(!fs::exists(d1));
+ }
+
+ // remove_symlink_tests ------------------------------------------------------------//
+
+ void remove_symlink_tests()
+ {
+ std::cout << "remove_symlink_tests..." << std::endl;
+
+ // remove() dangling symbolic link
+ fs::path link("dangling_link");
+ fs::remove(link); // remove any residue from past tests
+ BOOST_TEST(!fs::is_symlink(link));
+ BOOST_TEST(!fs::exists(link));
+ fs::create_symlink("nowhere", link);
+ BOOST_TEST(!fs::exists(link));
+ BOOST_TEST(fs::is_symlink(link));
+ BOOST_TEST(fs::remove(link));
+ BOOST_TEST(!fs::is_symlink(link));
+
+ // remove() self-refering symbolic link
+ link = "link_to_self";
+ fs::remove(link); // remove any residue from past tests
+ BOOST_TEST(!fs::is_symlink(link));
+ BOOST_TEST(!fs::exists(link));
+ fs::create_symlink(link, link);
+ BOOST_TEST(fs::remove(link));
+ BOOST_TEST(!fs::exists(link));
+ BOOST_TEST(!fs::is_symlink(link));
+
+ // remove() cyclic symbolic link
+ link = "link_to_a";
+ fs::path link2("link_to_b");
+ fs::remove(link); // remove any residue from past tests
+ fs::remove(link2); // remove any residue from past tests
+ BOOST_TEST(!fs::is_symlink(link));
+ BOOST_TEST(!fs::exists(link));
+ fs::create_symlink(link, link2);
+ fs::create_symlink(link2, link);
+ BOOST_TEST(fs::remove(link));
+ BOOST_TEST(fs::remove(link2));
+ BOOST_TEST(!fs::exists(link));
+ BOOST_TEST(!fs::exists(link2));
+ BOOST_TEST(!fs::is_symlink(link));
+
+ // remove() symbolic link to file
+ fs::path file_ph = "link_target";
+ fs::remove(file_ph); // remove any residue from past tests
+ BOOST_TEST(!fs::exists(file_ph));
+ create_file(file_ph, "");
+ BOOST_TEST(fs::exists(file_ph));
+ BOOST_TEST(!fs::is_directory(file_ph));
+ BOOST_TEST(fs::is_regular_file(file_ph));
+ link = "non_dangling_link";
+ fs::create_symlink(file_ph, link);
+ BOOST_TEST(fs::exists(link));
+ BOOST_TEST(!fs::is_directory(link));
+ BOOST_TEST(fs::is_regular_file(link));
+ BOOST_TEST(fs::is_symlink(link));
+ BOOST_TEST(fs::remove(link));
+ BOOST_TEST(fs::exists(file_ph));
+ BOOST_TEST(!fs::exists(link));
+ BOOST_TEST(!fs::is_symlink(link));
+ BOOST_TEST(fs::remove(file_ph));
+ BOOST_TEST(!fs::exists(file_ph));
+ }
+
+ // copy_file_tests -----------------------------------------------------------------//
+
+ void copy_file_tests(const fs::path& file_ph, const fs::path& d1)
+ {
+ std::cout << "copy_file_tests..." << std::endl;
+
+ BOOST_TEST(fs::exists(file_ph));
+ fs::remove(d1 / "f2"); // remove possible residue from prior testing
+ BOOST_TEST(fs::exists(d1));
+ BOOST_TEST(!fs::exists(d1 / "f2"));
+ std::cout << " copy " << file_ph << " to " << d1 / "f2" << std::endl;
+ fs::copy_file(file_ph, d1 / "f2");
+ std::cout << " copy complete" << std::endl;
+ BOOST_TEST(fs::exists(file_ph));
+ BOOST_TEST(fs::exists(d1 / "f2"));
+ BOOST_TEST(!fs::is_directory(d1 / "f2"));
+ verify_file(d1 / "f2", "foobar1");
+
+ bool copy_ex_ok = false;
+ try { fs::copy_file(file_ph, d1 / "f2"); }
+ catch (const fs::filesystem_error &) { copy_ex_ok = true; }
+ BOOST_TEST(copy_ex_ok);
+
+ copy_ex_ok = false;
+ try { fs::copy_file(file_ph, d1 / "f2", fs::copy_option::fail_if_exists); }
+ catch (const fs::filesystem_error &) { copy_ex_ok = true; }
+ BOOST_TEST(copy_ex_ok);
+
+ copy_ex_ok = true;
+ try { fs::copy_file(file_ph, d1 / "f2", fs::copy_option::overwrite_if_exists); }
+ catch (const fs::filesystem_error &) { copy_ex_ok = false; }
+ BOOST_TEST(copy_ex_ok);
+ }
+
+ // write_time_tests ----------------------------------------------------------------//
+
+ void write_time_tests(const fs::path& dir)
+ {
+ std::cout << "write_time_tests..." << std::endl;
+
+ fs::path file_ph = dir / "foobar2";
+ create_file(file_ph, "foobar2");
+ BOOST_TEST(fs::exists(file_ph));
+ BOOST_TEST(!fs::is_directory(file_ph));
+ BOOST_TEST(fs::is_regular_file(file_ph));
+ BOOST_TEST(fs::file_size(file_ph) == 7);
+ verify_file(file_ph, "foobar2");
+
+ // Some file system report last write time as local (FAT), while
+ // others (NTFS) report it as UTC. The C standard does not specify
+ // if time_t is local or UTC.
+
+ std::time_t ft = fs::last_write_time(file_ph);
+ std::cout << "\n UTC last_write_time() for a file just created is "
+ << std::asctime(std::gmtime(&ft)) << std::endl;
+
+ std::tm * tmp = std::localtime(&ft);
+ std::cout << "\n Year is " << tmp->tm_year << std::endl;
+ --tmp->tm_year;
+ std::cout << " Change year to " << tmp->tm_year << std::endl;
+ fs::last_write_time(file_ph, std::mktime(tmp));
+ std::time_t ft2 = fs::last_write_time(file_ph);
+ std::cout << " last_write_time() for the file is now "
+ << std::asctime(std::gmtime(&ft2)) << std::endl;
+ BOOST_TEST(ft != fs::last_write_time(file_ph));
+
+ std::cout << "\n Reset to current time" << std::endl;
+ fs::last_write_time(file_ph, ft);
+ double time_diff = std::difftime(ft, fs::last_write_time(file_ph));
+ std::cout
+ << " original last_write_time() - current last_write_time() is "
+ << time_diff << " seconds" << std::endl;
+ BOOST_TEST(time_diff >= -60.0 && time_diff <= 60.0);
+ }
+
+ // platform_specific_tests ---------------------------------------------------------//
+
+ void platform_specific_tests()
+ {
+ // Windows only tests
+ if (platform == "Windows")
+ {
+ std::cout << "Window specific tests..."
+ "\n (may take several seconds)" << std::endl;
+
+ BOOST_TEST(!fs::exists(fs::path("//share-not")));
+ BOOST_TEST(!fs::exists(fs::path("//share-not/")));
+ BOOST_TEST(!fs::exists(fs::path("//share-not/foo")));
+ BOOST_TEST(!fs::exists("tools/jam/src/:sys:stat.h")); // !exists() if ERROR_INVALID_NAME
+ BOOST_TEST(!fs::exists(":sys:stat.h")); // !exists() if ERROR_INVALID_PARAMETER
+ BOOST_TEST(dir.string().size() > 1
+ && dir.string()[1] == ':'); // verify path includes drive
+
+ BOOST_TEST(fs::system_complete("").empty());
+ BOOST_TEST(fs::system_complete("/") == fs::initial_path().root_path());
+ BOOST_TEST(fs::system_complete("foo")
+ == fs::initial_path() / "foo");
+
+ fs::path p1(fs::system_complete("/foo"));
+ BOOST_TEST_EQ(p1.string().size(), 6U); // this failed during v3 development due to bug
+ std::string s1(p1.string() );
+ std::string s2(fs::initial_path().root_path().string()+"foo");
+ BOOST_TEST_EQ(s1, s2);
+
+ BOOST_TEST(fs::complete(fs::path("c:/")).string()
+ == "c:/");
+ BOOST_TEST(fs::complete(fs::path("c:/foo")).string()
+ == "c:/foo");
+
+ BOOST_TEST(fs::system_complete(fs::path(fs::initial_path().root_name()))
+ == fs::initial_path());
+ BOOST_TEST(fs::system_complete(fs::path(fs::initial_path().root_name().string()
+ + "foo")).string() == fs::initial_path() / "foo");
+ BOOST_TEST(fs::system_complete(fs::path("c:/")).string()
+ == "c:/");
+ BOOST_TEST(fs::system_complete(fs::path("c:/foo")).string()
+ == "c:/foo");
+ BOOST_TEST(fs::system_complete(fs::path("//share")).string()
+ == "//share");
+ } // Windows
+
+ else if (platform == "POSIX")
+ {
+ std::cout << "POSIX specific tests..." << std::endl;
+ BOOST_TEST(fs::system_complete("").empty());
+ BOOST_TEST(fs::initial_path().root_path().string() == "/");
+ BOOST_TEST(fs::system_complete("/").string() == "/");
+ BOOST_TEST(fs::system_complete("foo").string()
+ == fs::initial_path().string()+"/foo");
+ BOOST_TEST(fs::system_complete("/foo").string()
+ == fs::initial_path().root_path().string()+"foo");
+ } // POSIX
+ }
+
+ // initial_tests -------------------------------------------------------------------//
+
+ void initial_tests()
+ {
+ std::cout << "initial_tests..." << std::endl;
+
+ std::cout << " initial_path().string() is\n \""
+ << fs::initial_path().string()
+ << "\"\n\n";
+ BOOST_TEST(fs::initial_path().is_complete());
+ BOOST_TEST(fs::current_path().is_complete());
+ BOOST_TEST(fs::initial_path().string()
+ == fs::current_path().string());
+
+ BOOST_TEST(fs::complete("").empty());
+ fs::path px1 = fs::complete("/");
+ fs::path px2 = fs::initial_path().root_path();
+ BOOST_TEST(px1 == px2);
+ BOOST_TEST(fs::complete("foo") == fs::initial_path().string()+"/foo");
+ BOOST_TEST(fs::complete("/foo") == fs::initial_path().root_path().string()+"foo");
+ BOOST_TEST(fs::complete("foo", fs::path("//net/bar"))
+ == "//net/bar/foo");
+ }
+
+ // space_tests ---------------------------------------------------------------------//
+
+ void space_tests()
+ {
+ std::cout << "space_tests..." << std::endl;
+
+ // make some reasonable assuptions for testing purposes
+ fs::space_info spi(fs::space(dir));
+ BOOST_TEST(spi.capacity > 1000000);
+ BOOST_TEST(spi.free > 1000);
+ BOOST_TEST(spi.capacity > spi.free);
+ BOOST_TEST(spi.free >= spi.available);
+
+ // 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';
+# endif
+ }
+
+ // equivalent_tests ----------------------------------------------------------------//
+
+ void equivalent_tests(const fs::path& file_ph)
+ {
+ std::cout << "equivalent_tests..." << std::endl;
+
+ BOOST_TEST(CHECK_EXCEPTION(bad_equivalent, ENOENT));
+ BOOST_TEST(fs::equivalent(file_ph, dir / "f1"));
+ BOOST_TEST(fs::equivalent(dir, d1 / ".."));
+ BOOST_TEST(!fs::equivalent(file_ph, dir));
+ BOOST_TEST(!fs::equivalent(dir, file_ph));
+ BOOST_TEST(!fs::equivalent(d1, d2));
+ BOOST_TEST(!fs::equivalent(dir, ng));
+ BOOST_TEST(!fs::equivalent(ng, dir));
+ BOOST_TEST(!fs::equivalent(file_ph, ng));
+ BOOST_TEST(!fs::equivalent(ng, file_ph));
+ }
+
   // _tests --------------------------------------------------------------------------//
 
   void _tests()
@@ -869,27 +1177,6 @@
 # endif
   std::cout << "API is " << platform << std::endl;
 
- exception_tests();
-
- std::cout << "\ninitial_path().string() is\n \""
- << fs::initial_path().string()
- << "\"\n\n";
- BOOST_TEST(fs::initial_path().is_complete());
- BOOST_TEST(fs::current_path().is_complete());
- BOOST_TEST(fs::initial_path().string()
- == fs::current_path().string());
-
- BOOST_TEST(fs::complete("").empty());
- fs::path px1 = fs::complete("/");
- fs::path px2 = fs::initial_path().root_path();
- BOOST_TEST(px1 == px2);
- BOOST_TEST(fs::complete("foo") == fs::initial_path().string()+"/foo");
- BOOST_TEST(fs::complete("/foo") == fs::initial_path().root_path().string()+"foo");
- BOOST_TEST(fs::complete("foo", fs::path("//net/bar"))
- == "//net/bar/foo");
-
- predicate_and_status_tests();
-
   dir = fs::initial_path() / temp_dir_name;
 
   if (fs::exists(dir))
@@ -899,102 +1186,22 @@
   }
   BOOST_TEST(!fs::exists(dir));
 
- create_directory_tests();
-
- // Windows only tests
- if (platform == "Windows")
- {
- std::cout << "Window specific tests..."
- "\n (may take several seconds)" << std::endl;
-
- BOOST_TEST(!fs::exists(fs::path("//share-not")));
- BOOST_TEST(!fs::exists(fs::path("//share-not/")));
- BOOST_TEST(!fs::exists(fs::path("//share-not/foo")));
- BOOST_TEST(!fs::exists("tools/jam/src/:sys:stat.h")); // !exists() if ERROR_INVALID_NAME
- BOOST_TEST(!fs::exists(":sys:stat.h")); // !exists() if ERROR_INVALID_PARAMETER
- BOOST_TEST(dir.string().size() > 1
- && dir.string()[1] == ':'); // verify path includes drive
-
- BOOST_TEST(fs::system_complete("").empty());
- BOOST_TEST(fs::system_complete("/") == fs::initial_path().root_path());
- BOOST_TEST(fs::system_complete("foo")
- == fs::initial_path() / "foo");
-
- fs::path p1(fs::system_complete("/foo"));
- BOOST_TEST_EQ(p1.string().size(), 6U); // this failed during v3 development due to bug
- std::string s1(p1.string() );
- std::string s2(fs::initial_path().root_path().string()+"foo");
- BOOST_TEST_EQ(s1, s2);
-
- BOOST_TEST(fs::complete(fs::path("c:/")).string()
- == "c:/");
- BOOST_TEST(fs::complete(fs::path("c:/foo")).string()
- == "c:/foo");
-
- BOOST_TEST(fs::system_complete(fs::path(fs::initial_path().root_name()))
- == fs::initial_path());
- BOOST_TEST(fs::system_complete(fs::path(fs::initial_path().root_name().string()
- + "foo")).string() == fs::initial_path() / "foo");
- BOOST_TEST(fs::system_complete(fs::path("c:/")).string()
- == "c:/");
- BOOST_TEST(fs::system_complete(fs::path("c:/foo")).string()
- == "c:/foo");
- BOOST_TEST(fs::system_complete(fs::path("//share")).string()
- == "//share");
- } // Windows
-
- else if (platform == "POSIX")
- {
- std::cout << "POSIX specific tests..." << std::endl;
- BOOST_TEST(fs::system_complete("").empty());
- BOOST_TEST(fs::initial_path().root_path().string() == "/");
- BOOST_TEST(fs::system_complete("/").string() == "/");
- BOOST_TEST(fs::system_complete("foo").string()
- == fs::initial_path().string()+"/foo");
- BOOST_TEST(fs::system_complete("/foo").string()
- == fs::initial_path().root_path().string()+"foo");
- } // POSIX
-
- // the bound functions should throw, so CHECK_EXCEPTION() should return true
- BOOST_TEST(CHECK_EXCEPTION(bad_file_size, ENOENT));
-
- // test path::exception members
- try { fs::file_size(ng); } // will throw
-
- catch (const fs::filesystem_error & ex)
- {
- BOOST_TEST(ex.path1().string() == " no-way, Jose");
- }
   // several functions give unreasonable results if uintmax_t isn't 64-bits
   std::cout << "sizeof(boost::uintmax_t) = " << sizeof(boost::uintmax_t) << '\n';
   BOOST_TEST(sizeof(boost::uintmax_t) >= 8);
 
+ initial_tests();
+ predicate_and_status_tests();
+ exception_tests();
+ platform_specific_tests();
+ create_directory_tests();
   current_directory_tests();
+ space_tests();
 
- // make some reasonable assuptions for testing purposes
- fs::space_info spi(fs::space(dir));
- BOOST_TEST(spi.capacity > 1000000);
- BOOST_TEST(spi.free > 1000);
- BOOST_TEST(spi.capacity > spi.free);
- BOOST_TEST(spi.free >= spi.available);
-
- // 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';
-# endif
-
- if (platform == "Windows")
- BOOST_TEST(CHECK_EXCEPTION(bad_directory_size, ENOENT));
- else
- BOOST_TEST(CHECK_EXCEPTION(bad_directory_size, 0));
-
+ // create directory d1, used by subsequent tests
   BOOST_TEST(!fs::create_directory(dir));
-
   BOOST_TEST(!fs::is_symlink(dir));
   BOOST_TEST(!fs::is_symlink("nosuchfileordirectory"));
-
   d1 = dir / "d1";
   BOOST_TEST(fs::create_directory(d1));
   BOOST_TEST(fs::exists(d1));
@@ -1006,7 +1213,7 @@
   directory_iterator_tests();
   create_directories_tests(); // must run AFTER directory_iterator_tests
 
- // create an empty file named "f0"
+ // create an empty file named "f0", used in subsequent tests
   fs::path file_ph(dir / "f0");
   create_file(file_ph, "");
   BOOST_TEST(fs::exists(file_ph));
@@ -1026,7 +1233,7 @@
   BOOST_TEST(!fs::is_other(stat));
   BOOST_TEST(!fs::is_symlink(stat));
 
- // create a file named "f1"
+ // create a file named "f1", used in subsequent tests
   file_ph = dir / "f1";
   create_file(file_ph, "foobar1");
 
@@ -1035,175 +1242,17 @@
   BOOST_TEST(fs::is_regular_file(file_ph));
   BOOST_TEST(fs::file_size(file_ph) == 7);
   verify_file(file_ph, "foobar1");
-
- // equivalence tests
- BOOST_TEST(CHECK_EXCEPTION(bad_equivalent, ENOENT));
- BOOST_TEST(fs::equivalent(file_ph, dir / "f1"));
- BOOST_TEST(fs::equivalent(dir, d1 / ".."));
- BOOST_TEST(!fs::equivalent(file_ph, dir));
- BOOST_TEST(!fs::equivalent(dir, file_ph));
- BOOST_TEST(!fs::equivalent(d1, d2));
- BOOST_TEST(!fs::equivalent(dir, ng));
- BOOST_TEST(!fs::equivalent(ng, dir));
- BOOST_TEST(!fs::equivalent(file_ph, ng));
- BOOST_TEST(!fs::equivalent(ng, file_ph));
   
+ equivalent_tests(file_ph);
   create_hard_link_tests();
   create_symlink_tests();
   resize_file_tests();
-
- // copy_file() tests
- std::cout << "begin copy_file test..." << std::endl;
- BOOST_TEST(fs::exists(file_ph));
- fs::remove(d1 / "f2"); // remove possible residue from prior testing
- BOOST_TEST(fs::exists(d1));
- BOOST_TEST(!fs::exists(d1 / "f2"));
- std::cout << " copy " << file_ph << " to " << d1 / "f2" << std::endl;
- fs::copy_file(file_ph, d1 / "f2");
- std::cout << " copy complete" << std::endl;
- BOOST_TEST(fs::exists(file_ph));
- BOOST_TEST(fs::exists(d1 / "f2"));
- BOOST_TEST(!fs::is_directory(d1 / "f2"));
- verify_file(d1 / "f2", "foobar1");
-
- bool copy_ex_ok = false;
- try { fs::copy_file(file_ph, d1 / "f2"); }
- catch (const fs::filesystem_error &) { copy_ex_ok = true; }
- BOOST_TEST(copy_ex_ok);
-
- copy_ex_ok = false;
- try { fs::copy_file(file_ph, d1 / "f2", fs::copy_option::fail_if_exists); }
- catch (const fs::filesystem_error &) { copy_ex_ok = true; }
- BOOST_TEST(copy_ex_ok);
-
- copy_ex_ok = true;
- try { fs::copy_file(file_ph, d1 / "f2", fs::copy_option::overwrite_if_exists); }
- catch (const fs::filesystem_error &) { copy_ex_ok = false; }
- BOOST_TEST(copy_ex_ok);
-
- std::cout << "copy_file test complete" << std::endl;
-
+ copy_file_tests(file_ph, d1);
   rename_tests();
-
- // remove() file
- file_ph = dir / "shortlife";
- BOOST_TEST(!fs::exists(file_ph));
- create_file(file_ph, "");
- BOOST_TEST(fs::exists(file_ph));
- BOOST_TEST(!fs::is_directory(file_ph));
- BOOST_TEST(fs::remove(file_ph));
- BOOST_TEST(!fs::exists(file_ph));
- BOOST_TEST(!fs::remove("no-such-file"));
- BOOST_TEST(!fs::remove("no-such-directory/no-such-file"));
-
- // remove() directory
- d1 = dir / "shortlife_dir";
- BOOST_TEST(!fs::exists(d1));
- fs::create_directory(d1);
- BOOST_TEST(fs::exists(d1));
- BOOST_TEST(fs::is_directory(d1));
- BOOST_TEST(fs::is_empty(d1));
- bad_remove_dir = dir;
- BOOST_TEST(CHECK_EXCEPTION(bad_remove, ENOTEMPTY));
- BOOST_TEST(fs::remove(d1));
- BOOST_TEST(!fs::exists(d1));
-
+ remove_tests(dir);
   if (create_symlink_ok) // only if symlinks supported
- {
- // remove() dangling symbolic link
- fs::path link("dangling_link");
- fs::remove(link); // remove any residue from past tests
- BOOST_TEST(!fs::is_symlink(link));
- BOOST_TEST(!fs::exists(link));
- fs::create_symlink("nowhere", link);
- BOOST_TEST(!fs::exists(link));
- BOOST_TEST(fs::is_symlink(link));
- BOOST_TEST(fs::remove(link));
- BOOST_TEST(!fs::is_symlink(link));
-
- // remove() self-refering symbolic link
- link = "link_to_self";
- fs::remove(link); // remove any residue from past tests
- BOOST_TEST(!fs::is_symlink(link));
- BOOST_TEST(!fs::exists(link));
- fs::create_symlink(link, link);
- BOOST_TEST(fs::remove(link));
- BOOST_TEST(!fs::exists(link));
- BOOST_TEST(!fs::is_symlink(link));
-
- // remove() cyclic symbolic link
- link = "link_to_a";
- fs::path link2("link_to_b");
- fs::remove(link); // remove any residue from past tests
- fs::remove(link2); // remove any residue from past tests
- BOOST_TEST(!fs::is_symlink(link));
- BOOST_TEST(!fs::exists(link));
- fs::create_symlink(link, link2);
- fs::create_symlink(link2, link);
- BOOST_TEST(fs::remove(link));
- BOOST_TEST(fs::remove(link2));
- BOOST_TEST(!fs::exists(link));
- BOOST_TEST(!fs::exists(link2));
- BOOST_TEST(!fs::is_symlink(link));
-
- // remove() symbolic link to file
- file_ph = "link_target";
- fs::remove(file_ph); // remove any residue from past tests
- BOOST_TEST(!fs::exists(file_ph));
- create_file(file_ph, "");
- BOOST_TEST(fs::exists(file_ph));
- BOOST_TEST(!fs::is_directory(file_ph));
- BOOST_TEST(fs::is_regular_file(file_ph));
- link = "non_dangling_link";
- fs::create_symlink(file_ph, link);
- BOOST_TEST(fs::exists(link));
- BOOST_TEST(!fs::is_directory(link));
- BOOST_TEST(fs::is_regular_file(link));
- BOOST_TEST(fs::is_symlink(link));
- BOOST_TEST(fs::remove(link));
- BOOST_TEST(fs::exists(file_ph));
- BOOST_TEST(!fs::exists(link));
- BOOST_TEST(!fs::is_symlink(link));
- BOOST_TEST(fs::remove(file_ph));
- BOOST_TEST(!fs::exists(file_ph));
- }
-
- // write time tests
-
- file_ph = dir / "foobar2";
- create_file(file_ph, "foobar2");
- BOOST_TEST(fs::exists(file_ph));
- BOOST_TEST(!fs::is_directory(file_ph));
- BOOST_TEST(fs::is_regular_file(file_ph));
- BOOST_TEST(fs::file_size(file_ph) == 7);
- verify_file(file_ph, "foobar2");
-
- // Some file system report last write time as local (FAT), while
- // others (NTFS) report it as UTC. The C standard does not specify
- // if time_t is local or UTC.
-
- std::time_t ft = fs::last_write_time(file_ph);
- std::cout << "\nUTC last_write_time() for a file just created is "
- << std::asctime(std::gmtime(&ft)) << std::endl;
-
- std::tm * tmp = std::localtime(&ft);
- std::cout << "\nYear is " << tmp->tm_year << std::endl;
- --tmp->tm_year;
- std::cout << "Change year to " << tmp->tm_year << std::endl;
- fs::last_write_time(file_ph, std::mktime(tmp));
- std::time_t ft2 = fs::last_write_time(file_ph);
- std::cout << "last_write_time() for the file is now "
- << std::asctime(std::gmtime(&ft2)) << std::endl;
- BOOST_TEST(ft != fs::last_write_time(file_ph));
-
-
- std::cout << "\nReset to current time" << std::endl;
- fs::last_write_time(file_ph, ft);
- double time_diff = std::difftime(ft, fs::last_write_time(file_ph));
- std::cout
- << "original last_write_time() - current last_write_time() is "
- << time_diff << " seconds" << std::endl;
- BOOST_TEST(time_diff >= -60.0 && time_diff <= 60.0);
+ remove_symlink_tests();
+ write_time_tests(dir);
 
   // post-test cleanup
   if (cleanup)


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