mirror of
https://github.com/boostorg/filesystem.git
synced 2026-01-29 19:42:08 +00:00
Align error codes to be based on POSIX
[SVN r29485]
This commit is contained in:
@@ -162,10 +162,11 @@ processing.</p>
|
||||
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
|
||||
|
||||
<p>Peter Dimov patiently identified requirements for portability and
|
||||
internationalization of error messages. </p>
|
||||
internationalization of error messages. He also suggested basing the portable
|
||||
error codes on POSIX.</p>
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->09 May, 2005<!--webbot bot="Timestamp" endspan i-checksum="14004" --></p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->08 June, 2005<!--webbot bot="Timestamp" endspan i-checksum="19924" --></p>
|
||||
|
||||
<p>© Copyright Beman Dawes, 2002</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
|
||||
@@ -24,6 +24,8 @@ Filesystem Library</h1>
|
||||
<a href="#Common_Specifications">Common Specifications</a><br>
|
||||
<a href="#Race-condition">Race-condition danger</a><br>
|
||||
<a href="#Implementation">Implementation</a><br>
|
||||
<a href="#narrow-only">Restricting library to narrow
|
||||
character paths</a><br>
|
||||
<a href="#Building">Building the object-library</a><br>
|
||||
<a href="#Cgywin">Notes for Cygwin users</a><br>
|
||||
<a href="#Acknowledgements">Acknowledgements</a><br>
|
||||
@@ -403,6 +405,13 @@ either the POSIX or Windows API.</p>
|
||||
<p>The library is in regular use on Apple OS X, HP-UX, IBM AIX, Linux,
|
||||
Microsoft Windows, SGI IRIX, and Sun Solaris operating systems using a variety
|
||||
of compilers.</p>
|
||||
<h2><a name="narrow-only">Restricting library to narrow character paths</a></h2>
|
||||
<p>Compilers or standard libraries which do not support wide characters (wchar_t)
|
||||
or wide character strings (std::wstring) are detected automatically, and cause
|
||||
the library to compile code that is restricted to narrow character paths
|
||||
(boost::filesystem::path). Users can force this restriction by defining the
|
||||
macro BOOST_FILESYSTEM_NARROW_ONLY. That may be useful for dealing with legacy
|
||||
compilers or operating systems.</p>
|
||||
<h2><a name="Building">Building</a> the object-library</h2>
|
||||
<p>The object-library will normally be built automatically. See
|
||||
<a href="../../../more/getting_started.html">Getting Started</a>. It can also be
|
||||
@@ -619,7 +628,7 @@ version 1.31.0.</p>
|
||||
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->29 May, 2005<!--webbot bot="Timestamp" endspan i-checksum="14006" --></p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->08 June, 2005<!--webbot bot="Timestamp" endspan i-checksum="19924" --></p>
|
||||
|
||||
<p>© Copyright Beman Dawes, 2002-2005</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
|
||||
23
include/boost/filesystem/cerrno.hpp
Normal file
23
include/boost/filesystem/cerrno.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Boost Filesystem cerrno.hpp header --------------------------------------//
|
||||
|
||||
// © Copyright Beman Dawes 2005.
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See library home page at http://www.boost.org/libs/filesystem
|
||||
|
||||
#ifndef BOOST_FILESYSTEM_CERRNO_HPP
|
||||
#define BOOST_FILESYSTEM_CERRNO_HPP
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
#if defined __BORLANDC__
|
||||
#define ENOSYS 9997
|
||||
#endif
|
||||
|
||||
#define EBADHANDLE 9998 // bad handle
|
||||
#define EOTHERERR 9999 // Other operating system error not translatable
|
||||
// to a POSIX errno value
|
||||
|
||||
#endif // include guard
|
||||
@@ -79,35 +79,23 @@ namespace boost
|
||||
};
|
||||
# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY
|
||||
|
||||
enum error_code
|
||||
{
|
||||
no_error = 0,
|
||||
system_error, // system generated error; if possible, is translated
|
||||
// to one of the more specific errors below.
|
||||
other_error, // library generated error
|
||||
security_error, // includes access rights, permissions failures
|
||||
read_only_error,
|
||||
io_error,
|
||||
path_error, // such as bad syntax
|
||||
not_found_error,
|
||||
not_directory_error,
|
||||
busy_error, // implies trying again might succeed
|
||||
not_ready_error, // ditto
|
||||
already_exists_error,
|
||||
not_empty_error,
|
||||
is_directory_error,
|
||||
out_of_space_error,
|
||||
out_of_memory_error,
|
||||
out_of_resource_error
|
||||
};
|
||||
typedef int errno_type; // determined by C standard
|
||||
typedef int system_error_type; // both POSIX and Windows use int
|
||||
|
||||
typedef int system_error_type;
|
||||
# ifdef BOOST_WINDOWS_API
|
||||
BOOST_FILESYSTEM_DECL
|
||||
errno_type lookup_errno( system_error_type sys_err_code );
|
||||
# else
|
||||
inline errno_type lookup_errno( system_error_type sys_err_code )
|
||||
{ return sys_err_code; }
|
||||
# endif
|
||||
|
||||
BOOST_FILESYSTEM_DECL error_code
|
||||
lookup_error_code( system_error_type sys_err_code );
|
||||
|
||||
BOOST_FILESYSTEM_DECL void
|
||||
system_message( system_error_type sys_err_code, std::string & target );
|
||||
// deprecated support for legacy function name
|
||||
inline errno_type lookup_error_code( system_error_type sys_err_code )
|
||||
{ return lookup_errno( sys_err_code ); }
|
||||
|
||||
BOOST_FILESYSTEM_DECL
|
||||
void system_message( system_error_type sys_err_code, std::string & target );
|
||||
// Effects: appends error message to target
|
||||
|
||||
# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
|
||||
@@ -475,7 +463,7 @@ namespace boost
|
||||
typename String::size_type size = -1
|
||||
)
|
||||
{
|
||||
if ( size == -1 ) size = src.size();
|
||||
if ( size == String::npos ) size = src.size();
|
||||
element_pos = 0;
|
||||
element_size = 0;
|
||||
if ( src.empty() ) return;
|
||||
@@ -592,7 +580,7 @@ namespace boost
|
||||
&& m_path[end_pos] == path_separator<path_type>::value );
|
||||
|
||||
// skip separators unless root directory
|
||||
string_type::size_type root_dir_pos( detail::root_directory_start
|
||||
typename string_type::size_type root_dir_pos( detail::root_directory_start
|
||||
<string_type, traits_type>( m_path, end_pos ) );
|
||||
for ( ;
|
||||
end_pos > 0
|
||||
@@ -644,7 +632,7 @@ namespace boost
|
||||
template<class String, class Traits>
|
||||
String basic_path<String, Traits>::root_directory() const
|
||||
{
|
||||
string_type::size_type start(
|
||||
typename string_type::size_type start(
|
||||
detail::root_directory_start<String, Traits>( m_path, m_path.size() ) );
|
||||
|
||||
return start == string_type::npos
|
||||
@@ -730,7 +718,7 @@ namespace boost
|
||||
template<class String, class Traits>
|
||||
basic_path<String, Traits> & basic_path<String, Traits>::canonize()
|
||||
{
|
||||
static const string_type::value_type dot[]
|
||||
static const typename string_type::value_type dot[]
|
||||
= { path_relative<path_type>::value, 0 };
|
||||
|
||||
if ( m_path.empty() ) return *this;
|
||||
@@ -752,7 +740,7 @@ namespace boost
|
||||
template<class String, class Traits>
|
||||
basic_path<String, Traits> & basic_path<String, Traits>::normalize()
|
||||
{
|
||||
static const string_type::value_type dot[]
|
||||
static const typename string_type::value_type dot[]
|
||||
= { path_relative<path_type>::value, 0 };
|
||||
|
||||
if ( m_path.empty() ) return *this;
|
||||
@@ -796,7 +784,7 @@ namespace boost
|
||||
&& temp.m_path[temp.m_path.size()-1]
|
||||
== path_separator<path_type>::value )
|
||||
{
|
||||
string_type::size_type rds(
|
||||
typename string_type::size_type rds(
|
||||
detail::root_directory_start<String,Traits>( temp.m_path,
|
||||
temp.m_path.size() ) );
|
||||
if ( rds == string_type::npos
|
||||
@@ -839,11 +827,11 @@ namespace boost
|
||||
// for Windows, use the alternate separator, and bypass extra
|
||||
// root separators
|
||||
|
||||
string_type::size_type root_dir_start(
|
||||
typename string_type::size_type root_dir_start(
|
||||
detail::root_directory_start<String, Traits>( m_path, m_path.size() ) );
|
||||
bool in_root( root_dir_start != string_type::npos );
|
||||
String s;
|
||||
for ( string_type::size_type pos( 0 );
|
||||
for ( typename string_type::size_type pos( 0 );
|
||||
pos != m_path.size(); ++pos )
|
||||
{
|
||||
// special case // [net]
|
||||
@@ -891,7 +879,7 @@ namespace boost
|
||||
{
|
||||
iterator itr;
|
||||
itr.m_path_ptr = this;
|
||||
string_type::size_type element_size;
|
||||
typename string_type::size_type element_size;
|
||||
detail::first_element<String, Traits>( m_path, itr.m_pos, element_size );
|
||||
itr.m_name = m_path.substr( itr.m_pos, element_size );
|
||||
return itr;
|
||||
@@ -954,7 +942,7 @@ namespace boost
|
||||
}
|
||||
|
||||
typedef typename Path::string_type string_type;
|
||||
string_type::size_type end_pos(
|
||||
typename string_type::size_type end_pos(
|
||||
ph.m_path_ptr->m_path.find( path_separator<Path>::value, ph.m_pos ) );
|
||||
# ifdef BOOST_WINDOWS_PATH
|
||||
if ( end_pos == string_type::npos )
|
||||
@@ -973,17 +961,17 @@ namespace boost
|
||||
|
||||
typedef typename Path::string_type string_type;
|
||||
|
||||
static const string_type::value_type separators[] = {
|
||||
static const typename string_type::value_type separators[] = {
|
||||
path_separator<Path>::value,
|
||||
# ifdef BOOST_WINDOWS_PATH
|
||||
path_alt_separator<Path>::value,
|
||||
# endif
|
||||
0 };
|
||||
|
||||
string_type::size_type end_pos( ph.m_pos );
|
||||
typename string_type::size_type end_pos( ph.m_pos );
|
||||
|
||||
string_type::size_type root_dir_pos( detail::root_directory_start
|
||||
<string_type, typename Path::traits_type>(
|
||||
typename string_type::size_type root_dir_pos(
|
||||
detail::root_directory_start<string_type, typename Path::traits_type>(
|
||||
ph.m_path_ptr->m_path, end_pos ) );
|
||||
|
||||
// if at end and there was a trailing non-root '/', return "."
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <boost/filesystem/config.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/cerrno.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
@@ -25,10 +26,9 @@ namespace fs = boost::filesystem;
|
||||
namespace std { using ::strerror; }
|
||||
# endif
|
||||
|
||||
|
||||
# if defined( BOOST_WINDOWS_API )
|
||||
# include "windows.h"
|
||||
# else
|
||||
# include <errno.h> // for POSIX error codes
|
||||
# endif
|
||||
|
||||
#include <boost/config/abi_prefix.hpp> // must be the last header
|
||||
@@ -37,62 +37,59 @@ namespace fs = boost::filesystem;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ec_xlate { int sys_ec; fs::error_code ec; };
|
||||
#ifdef BOOST_WINDOWS_API
|
||||
struct ec_xlate { fs::system_error_type sys_ec; fs::errno_type ec; };
|
||||
const ec_xlate ec_table[] =
|
||||
{
|
||||
# ifdef BOOST_WINDOWS_API
|
||||
{ 0, fs::other_error },
|
||||
{ ERROR_ACCESS_DENIED, fs::security_error },
|
||||
{ ERROR_INVALID_ACCESS, fs::security_error },
|
||||
{ ERROR_SHARING_VIOLATION, fs::security_error },
|
||||
{ ERROR_LOCK_VIOLATION, fs::security_error },
|
||||
{ ERROR_LOCKED, fs::security_error },
|
||||
{ ERROR_NOACCESS, fs::security_error },
|
||||
{ ERROR_WRITE_PROTECT, fs::read_only_error },
|
||||
{ ERROR_NOT_READY, fs::not_ready_error },
|
||||
{ ERROR_SEEK, fs::io_error },
|
||||
{ ERROR_READ_FAULT, fs::io_error },
|
||||
{ ERROR_WRITE_FAULT, fs::io_error },
|
||||
{ ERROR_CANTOPEN, fs::io_error },
|
||||
{ ERROR_CANTREAD, fs::io_error },
|
||||
{ ERROR_CANTWRITE, fs::io_error },
|
||||
{ ERROR_DIRECTORY, fs::path_error },
|
||||
{ ERROR_INVALID_NAME, fs::path_error },
|
||||
{ ERROR_FILE_NOT_FOUND, fs::not_found_error },
|
||||
{ ERROR_PATH_NOT_FOUND, fs::not_found_error },
|
||||
{ ERROR_DEV_NOT_EXIST, fs::not_found_error },
|
||||
{ ERROR_DEVICE_IN_USE, fs::busy_error },
|
||||
{ ERROR_OPEN_FILES, fs::busy_error },
|
||||
{ ERROR_BUSY_DRIVE, fs::busy_error },
|
||||
{ ERROR_BUSY, fs::busy_error },
|
||||
{ ERROR_FILE_EXISTS, fs::already_exists_error },
|
||||
{ ERROR_ALREADY_EXISTS, fs::already_exists_error },
|
||||
{ ERROR_DIR_NOT_EMPTY, fs::not_empty_error },
|
||||
{ ERROR_HANDLE_DISK_FULL, fs::out_of_space_error },
|
||||
{ ERROR_DISK_FULL, fs::out_of_space_error },
|
||||
{ ERROR_OUTOFMEMORY, fs::out_of_memory_error },
|
||||
{ ERROR_NOT_ENOUGH_MEMORY, fs::out_of_memory_error },
|
||||
{ ERROR_TOO_MANY_OPEN_FILES, fs::out_of_resource_error }
|
||||
# else
|
||||
{ 0, fs::other_error },
|
||||
{ EACCES, fs::security_error },
|
||||
{ EROFS, fs::read_only_error },
|
||||
{ EIO, fs::io_error },
|
||||
{ EINVAL, fs::path_error },
|
||||
{ ENAMETOOLONG, fs::path_error },
|
||||
{ ENOENT, fs::not_found_error },
|
||||
{ ENOTDIR, fs::not_directory_error },
|
||||
{ EAGAIN, fs::busy_error },
|
||||
{ EBUSY, fs::busy_error },
|
||||
{ ETXTBSY, fs::busy_error },
|
||||
{ EEXIST, fs::already_exists_error },
|
||||
{ ENOTEMPTY, fs::not_empty_error },
|
||||
{ EISDIR, fs::is_directory_error },
|
||||
{ ENOSPC, fs::out_of_space_error },
|
||||
{ ENOMEM, fs::out_of_memory_error },
|
||||
{ EMFILE, fs::out_of_resource_error }
|
||||
# endif
|
||||
// see WinError.h comments for descriptions of errors
|
||||
|
||||
// most common errors first to speed sequential search
|
||||
{ ERROR_FILE_NOT_FOUND, ENOENT },
|
||||
{ ERROR_PATH_NOT_FOUND, ENOENT },
|
||||
|
||||
// alphabetical for easy maintenance
|
||||
{ 0, 0 }, // no error
|
||||
{ ERROR_ACCESS_DENIED, EACCES },
|
||||
{ ERROR_ALREADY_EXISTS, EEXIST },
|
||||
{ ERROR_BAD_UNIT, ENODEV },
|
||||
{ ERROR_BUFFER_OVERFLOW, ENAMETOOLONG },
|
||||
{ ERROR_BUSY, EBUSY },
|
||||
{ ERROR_BUSY_DRIVE, EBUSY },
|
||||
{ ERROR_CANNOT_MAKE, EACCES },
|
||||
{ ERROR_CANTOPEN, EIO },
|
||||
{ ERROR_CANTREAD, EIO },
|
||||
{ ERROR_CANTWRITE, EIO },
|
||||
{ ERROR_CURRENT_DIRECTORY, EACCES },
|
||||
{ ERROR_DEV_NOT_EXIST, ENODEV },
|
||||
{ ERROR_DEVICE_IN_USE, EBUSY },
|
||||
{ ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
|
||||
{ ERROR_DIRECTORY, EINVAL }, // WinError.h: "The directory name is invalid"
|
||||
{ ERROR_DISK_FULL, ENOSPC },
|
||||
{ ERROR_FILE_EXISTS, EEXIST },
|
||||
{ ERROR_HANDLE_DISK_FULL, ENOSPC },
|
||||
{ ERROR_INVALID_ACCESS, EACCES },
|
||||
{ ERROR_INVALID_DRIVE, ENODEV },
|
||||
{ ERROR_INVALID_FUNCTION, ENOSYS },
|
||||
{ ERROR_INVALID_HANDLE, EBADHANDLE },
|
||||
{ ERROR_INVALID_NAME, EINVAL },
|
||||
{ ERROR_LOCK_VIOLATION, EACCES },
|
||||
{ ERROR_LOCKED, EACCES },
|
||||
{ ERROR_NOACCESS, EACCES },
|
||||
{ ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
|
||||
{ ERROR_NOT_READY, EAGAIN },
|
||||
{ ERROR_NOT_SAME_DEVICE, EXDEV },
|
||||
{ ERROR_OPEN_FAILED, EIO },
|
||||
{ ERROR_OPEN_FILES, EBUSY },
|
||||
{ ERROR_OUTOFMEMORY, ENOMEM },
|
||||
{ ERROR_READ_FAULT, EIO },
|
||||
{ ERROR_SEEK, EIO },
|
||||
{ ERROR_SHARING_VIOLATION, EACCES },
|
||||
{ ERROR_TOO_MANY_OPEN_FILES, ENFILE },
|
||||
{ ERROR_WRITE_FAULT, EIO },
|
||||
{ ERROR_WRITE_PROTECT, EROFS },
|
||||
{ 0,EOTHERERR }
|
||||
};
|
||||
#endif
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
@@ -100,8 +97,10 @@ namespace boost
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
BOOST_FILESYSTEM_DECL error_code
|
||||
lookup_error_code( system_error_type sys_err_code )
|
||||
# ifdef BOOST_WINDOWS_API
|
||||
|
||||
BOOST_FILESYSTEM_DECL
|
||||
errno_type lookup_errno( system_error_type sys_err_code )
|
||||
{
|
||||
for ( const ec_xlate * cur = &ec_table[0];
|
||||
cur != ec_table
|
||||
@@ -109,10 +108,9 @@ namespace boost
|
||||
{
|
||||
if ( sys_err_code == cur->sys_ec ) return cur->ec;
|
||||
}
|
||||
return system_error; // general system error code
|
||||
return EOTHERERR;
|
||||
}
|
||||
|
||||
# ifdef BOOST_WINDOWS_API
|
||||
BOOST_FILESYSTEM_DECL void
|
||||
system_message( system_error_type sys_err_code, std::string & target )
|
||||
{
|
||||
|
||||
@@ -622,7 +622,11 @@ namespace boost
|
||||
dir_itr_first(
|
||||
void *& handle, const std::wstring & dir, std::wstring & target )
|
||||
{
|
||||
std::wstring dirpath( dir + L"/*" );
|
||||
// use a form of search Sebastian Martel reports will work with Win98
|
||||
std::wstring dirpath( dir );
|
||||
dirpath += (dirpath.empty()
|
||||
|| dirpath[dirpath.size()-1] != L'\\') ? L"\\*" : L"*";
|
||||
|
||||
WIN32_FIND_DATAW data;
|
||||
if ( (handle = ::FindFirstFileW( dirpath.c_str(), &data ))
|
||||
== INVALID_HANDLE_VALUE )
|
||||
@@ -718,7 +722,11 @@ namespace boost
|
||||
// causes a ERROR_FILE_NOT_FOUND error which we do not considered an
|
||||
// error. It is treated as eof instead.
|
||||
{
|
||||
std::string dirpath( dir + "/*" );
|
||||
// use a form of search Sebastian Martel reports will work with Win98
|
||||
std::string dirpath( dir );
|
||||
dirpath += (dirpath.empty()
|
||||
|| dirpath[dirpath.size()-1] != '\\') ? "\\*" : "*";
|
||||
|
||||
WIN32_FIND_DATAA data;
|
||||
if ( (handle = ::FindFirstFileA( dirpath.c_str(), &data ))
|
||||
== INVALID_HANDLE_VALUE )
|
||||
|
||||
@@ -28,21 +28,20 @@ using fs::path;
|
||||
namespace
|
||||
{
|
||||
template< typename F >
|
||||
bool throws_fs_error( F func, fs::error_code ec =
|
||||
::boost::filesystem::no_error ) // VC++ 7.1 build 2292 won't accept fs::
|
||||
bool throws_fs_error( F func, fs::errno_type ec = 0 )
|
||||
{
|
||||
try { func(); }
|
||||
|
||||
catch ( const fs::filesystem_error & ex )
|
||||
{
|
||||
if ( ec == fs::no_error
|
||||
if ( ec == 0
|
||||
|| ec == fs::lookup_error_code(ex.system_error()) ) return true;
|
||||
std::cout
|
||||
<< "exception reports " << fs::lookup_error_code(ex.system_error())
|
||||
<< ", should be " << ec
|
||||
<< "\n system_error() is " << ex.system_error()
|
||||
<< std::endl;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace std
|
||||
return s1 == e ? 0 : (*s1<*s2 ? -1 : 1);
|
||||
}
|
||||
static size_t length(const char_type* s)
|
||||
{ const char_type* b=s; for(;*s!=0L;++s); return s-b; }
|
||||
{ const char_type* b=s; for(;*s!=0L;++s){} return s-b; }
|
||||
|
||||
static const char_type* find(const char_type* s, size_t n, const char_type& a)
|
||||
{ return 0; }
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// See library home page at http://www.boost.org/libs/filesystem
|
||||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/cerrno.hpp>
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
#include <boost/config.hpp>
|
||||
@@ -19,7 +20,6 @@ using boost::bind;
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cerrno>
|
||||
#include <ctime>
|
||||
|
||||
#ifndef BOOST_FILESYSTEM_NARROW_ONLY
|
||||
@@ -42,6 +42,8 @@ using boost::bind;
|
||||
using ::difftime; using ::time; using ::tm; using ::mktime; }
|
||||
# endif
|
||||
|
||||
#define CHECK_EXCEPTION(b,e) throws_fs_error(b,e,__LINE__)
|
||||
|
||||
namespace
|
||||
{
|
||||
bool report_throws;
|
||||
@@ -70,22 +72,21 @@ namespace
|
||||
}
|
||||
|
||||
template< typename F >
|
||||
bool throws_fs_error( F func, fs::error_code ec =
|
||||
::boost::filesystem::no_error ) // VC++ 7.1 build 2292 won't accept fs::
|
||||
bool throws_fs_error( F func, fs::errno_type ec, int line )
|
||||
{
|
||||
try { func(); }
|
||||
|
||||
catch ( const fs::filesystem_error & ex )
|
||||
{
|
||||
if ( report_throws ) std::cout << ex.what() << "\n";
|
||||
if ( ec == fs::no_error
|
||||
if ( ec == 0
|
||||
|| ec == fs::lookup_error_code(ex.system_error()) ) return true;
|
||||
std::cout
|
||||
<< "exception reports " << fs::lookup_error_code(ex.system_error())
|
||||
<< "\nline " << line
|
||||
<< " exception reports " << fs::lookup_error_code(ex.system_error())
|
||||
<< ", should be " << ec
|
||||
<< "\n system_error() is " << ex.system_error()
|
||||
<< std::endl;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -132,10 +133,10 @@ int test_main( int argc, char * argv[] )
|
||||
# endif
|
||||
std::cout << "API is " << platform << '\n';
|
||||
|
||||
std::cout << "initial_path<path>().string() is\n \""
|
||||
std::cout << "\ninitial_path<path>().string() is\n \""
|
||||
<< fs::initial_path<fs::path>().string()
|
||||
<< "\"\n";
|
||||
std::cout << "initial_path<fs::path>().file_string() is\n \""
|
||||
std::cout << "\ninitial_path<fs::path>().file_string() is\n \""
|
||||
<< fs::initial_path<fs::path>().file_string()
|
||||
<< "\"\n";
|
||||
BOOST_CHECK( fs::initial_path<fs::path>().is_complete() );
|
||||
@@ -147,6 +148,8 @@ int test_main( int argc, char * argv[] )
|
||||
BOOST_CHECK( fs::complete( "/" ).string() == fs::initial_path<fs::path>().root_path().string() );
|
||||
BOOST_CHECK( fs::complete( "foo" ).string() == fs::initial_path<fs::path>().string()+"/foo" );
|
||||
BOOST_CHECK( fs::complete( "/foo" ).string() == fs::initial_path<fs::path>().root_path().string()+"foo" );
|
||||
BOOST_CHECK( fs::complete( "foo", fs::path( "//net/bar" ) ).string()
|
||||
== "//net/bar/foo" );
|
||||
|
||||
// predicate and status tests
|
||||
fs::path ng( " no-way, Jose" );
|
||||
@@ -177,8 +180,6 @@ int test_main( int argc, char * argv[] )
|
||||
== "c:/" );
|
||||
BOOST_CHECK( fs::complete( fs::path( "c:/foo" ) ).string()
|
||||
== "c:/foo" );
|
||||
BOOST_CHECK( fs::complete( fs::path( "//share" ) ).string()
|
||||
== "//share" );
|
||||
|
||||
BOOST_CHECK( fs::system_complete( fs::path( fs::initial_path<fs::path>().root_name() ) ).string() == fs::initial_path<fs::path>().string() );
|
||||
BOOST_CHECK( fs::system_complete( fs::path( fs::initial_path<fs::path>().root_name()
|
||||
@@ -205,8 +206,8 @@ int test_main( int argc, char * argv[] )
|
||||
fs::remove_all( dir ); // in case residue from prior failed tests
|
||||
BOOST_CHECK( !fs::exists( dir ) );
|
||||
|
||||
// the bound functions should throw, so throws_fs_error() should return true
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::file_size), ng ), fs::not_found_error ) );
|
||||
// the bound functions should throw, so CHECK_EXCEPTION() should return true
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::file_size), ng ), ENOENT ) );
|
||||
|
||||
// test path::exception members
|
||||
try { fs::file_size( ng ); } // will throw
|
||||
@@ -221,8 +222,12 @@ int test_main( int argc, char * argv[] )
|
||||
BOOST_CHECK( fs::exists( dir ) );
|
||||
BOOST_CHECK( BOOST_FS_IS_EMPTY( dir ) );
|
||||
BOOST_CHECK( fs::is_directory( dir ) );
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::file_size), dir ),
|
||||
fs::is_directory_error ) );
|
||||
if ( platform == "Windows" )
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::file_size), dir ),
|
||||
ENOENT ) );
|
||||
else
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::file_size), dir ),
|
||||
EISDIR ) );
|
||||
BOOST_CHECK( !fs::create_directory( dir ) );
|
||||
|
||||
BOOST_CHECK( !fs::is_symlink( dir ) );
|
||||
@@ -302,8 +307,8 @@ int test_main( int argc, char * argv[] )
|
||||
BOOST_CHECK( fs::is_file( file_ph ) );
|
||||
BOOST_CHECK( BOOST_FS_IS_EMPTY( file_ph ) );
|
||||
BOOST_CHECK( fs::file_size( file_ph ) == 0 );
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::create_directory),
|
||||
file_ph ), fs::not_directory_error ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::create_directory),
|
||||
file_ph ), EEXIST ) );
|
||||
// create a file named "f1"
|
||||
file_ph = dir / "f1";
|
||||
create_file( file_ph, "foobar1" );
|
||||
@@ -316,7 +321,8 @@ int test_main( int argc, char * argv[] )
|
||||
|
||||
// equivalence tests
|
||||
fs::path ng2("does_not_exist2");
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::equivalent), ng, ng2 ) ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION(
|
||||
bind( BOOST_BND(fs::equivalent), ng, ng2 ), ENOENT ) );
|
||||
BOOST_CHECK( fs::equivalent( file_ph, dir / "f1" ) );
|
||||
BOOST_CHECK( fs::equivalent( dir, d1 / ".." ) );
|
||||
BOOST_CHECK( !fs::equivalent( file_ph, dir ) );
|
||||
@@ -348,8 +354,9 @@ int test_main( int argc, char * argv[] )
|
||||
BOOST_CHECK( fs::exists( link_ph ) );
|
||||
BOOST_CHECK( fs::exists( file_ph ) );
|
||||
BOOST_CHECK( fs::equivalent( link_ph, file_ph ) );
|
||||
BOOST_CHECK( throws_fs_error(
|
||||
bind( BOOST_BND(fs::create_hard_link), dir, dir/"shouldnotwork" ), fs::not_found_error ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION(
|
||||
bind( BOOST_BND(fs::create_hard_link), dir, dir/"shouldnotwork" ),
|
||||
0 ) );
|
||||
}
|
||||
// there was an inital bug in directory_iterator that caused premature
|
||||
// close of an OS handle. This block will detect regression.
|
||||
@@ -374,28 +381,29 @@ int test_main( int argc, char * argv[] )
|
||||
// [case 1] make sure can't rename() a non-existent file
|
||||
BOOST_CHECK( !fs::exists( d1 / "f99" ) );
|
||||
BOOST_CHECK( !fs::exists( d1 / "f98" ) );
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::rename), d1 / "f99", d1 / "f98" ),
|
||||
fs::not_found_error ) );
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::rename), fs::path(""), d1 / "f98" ),
|
||||
fs::not_found_error ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::rename), d1 / "f99", d1 / "f98" ),
|
||||
ENOENT ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::rename), fs::path(""), d1 / "f98" ),
|
||||
ENOENT ) );
|
||||
|
||||
// [case 2] rename() target.empty()
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::rename), file_ph, "" ),
|
||||
fs::not_found_error ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::rename), file_ph, "" ),
|
||||
ENOENT ) );
|
||||
|
||||
// [case 3] make sure can't rename() to an existent file or directory
|
||||
BOOST_CHECK( fs::exists( dir / "f1" ) );
|
||||
BOOST_CHECK( fs::exists( d1 / "f2" ) );
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::rename), dir / "f1", d1 / "f2" ) ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::rename),
|
||||
dir / "f1", d1 / "f2" ), EEXIST ) );
|
||||
// several POSIX implementations (cygwin, openBSD) report ENOENT instead of EEXIST,
|
||||
// so we don't verify error type on the above test.
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::rename), dir, d1 ) ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::rename), dir, d1 ), 0 ) );
|
||||
|
||||
// [case 4A] can't rename() file to a nonexistent parent directory
|
||||
BOOST_CHECK( !fs::is_directory( dir / "f1" ) );
|
||||
BOOST_CHECK( !fs::exists( dir / "d3/f3" ) );
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::rename), dir / "f1", dir / "d3/f3" ),
|
||||
fs::not_found_error ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::rename), dir / "f1", dir / "d3/f3" ),
|
||||
ENOENT ) );
|
||||
|
||||
// [case 4B] rename() file in same directory
|
||||
BOOST_CHECK( fs::exists( d1 / "f2" ) );
|
||||
@@ -421,8 +429,8 @@ int test_main( int argc, char * argv[] )
|
||||
BOOST_CHECK( fs::exists( d1 ) );
|
||||
BOOST_CHECK( !fs::exists( dir / "d3/d5" ) );
|
||||
BOOST_CHECK( !fs::exists( dir / "d3" ) );
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::rename), d1, dir / "d3/d5" ),
|
||||
fs::not_found_error ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::rename), d1, dir / "d3/d5" ),
|
||||
ENOENT ) );
|
||||
|
||||
// [case 5B] rename() on directory
|
||||
fs::path d3( dir / "d3" );
|
||||
@@ -471,7 +479,7 @@ int test_main( int argc, char * argv[] )
|
||||
BOOST_CHECK( fs::exists( d1 ) );
|
||||
BOOST_CHECK( fs::is_directory( d1 ) );
|
||||
BOOST_CHECK( BOOST_FS_IS_EMPTY( d1 ) );
|
||||
BOOST_CHECK( throws_fs_error( bind( BOOST_BND(fs::remove), dir ), fs::not_empty_error ) );
|
||||
BOOST_CHECK( CHECK_EXCEPTION( bind( BOOST_BND(fs::remove), dir ), ENOTEMPTY ) );
|
||||
BOOST_CHECK( fs::remove( d1 ) );
|
||||
BOOST_CHECK( !fs::exists( d1 ) );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user