]> git.lyx.org Git - features.git/blob - boost/libs/filesystem/src/exception.cpp
boost::filesystem added
[features.git] / boost / libs / filesystem / src / exception.cpp
1 //  Exception implementation file  -------------------------------------------//
2
3 // < ----------------------------------------------------------------------- >
4 // <   Copyright © 2002 Beman Dawes                                          >
5 // <   Copyright © 2001 Dietmar Kühl, All Rights Reserved                    > 
6 // <                                                                         > 
7 // <   Permission to use, copy, modify, distribute and sell this             > 
8 // <   software for any purpose is hereby granted without fee, provided      > 
9 // <   that the above copyright notice appears in all copies and that        > 
10 // <   both that copyright notice and this permission notice appear in       > 
11 // <   supporting documentation. The authors make no representations about   > 
12 // <   the suitability of this software for any purpose. It is provided      > 
13 // <   "as is" without express or implied warranty.                          > 
14 // < ----------------------------------------------------------------------- > 
15
16 //  See http://www.boost.org/libs/filesystem for documentation.
17
18 //----------------------------------------------------------------------------//
19
20 #include <boost/config.hpp>
21 #include <boost/filesystem/exception.hpp>
22
23 namespace fs = boost::filesystem;
24
25 #include <cstring> // SGI MIPSpro compilers need this
26 #include <string>
27
28 # ifdef BOOST_NO_STDC_NAMESPACE
29     namespace std { using ::strerror; }
30 # endif
31
32 // BOOST_POSIX or BOOST_WINDOWS specify which API to use.
33 # if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
34 #   if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
35 #     define BOOST_WINDOWS
36 #   else
37 #     define BOOST_POSIX
38 #   endif
39 # endif
40
41 # if defined( BOOST_WINDOWS )
42 #   include "windows.h"
43 # else
44 #   include <errno.h> // for POSIX error codes
45 # endif
46
47 //----------------------------------------------------------------------------//
48
49 namespace
50 {
51   std::string system_message( int sys_err_code )
52   {
53     std::string str;
54 # ifdef BOOST_WINDOWS
55     LPVOID lpMsgBuf;
56     ::FormatMessageA( 
57         FORMAT_MESSAGE_ALLOCATE_BUFFER | 
58         FORMAT_MESSAGE_FROM_SYSTEM | 
59         FORMAT_MESSAGE_IGNORE_INSERTS,
60         NULL,
61         sys_err_code,
62         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
63         (LPSTR) &lpMsgBuf,
64         0,
65         NULL 
66     );
67     str += static_cast<LPCSTR>(lpMsgBuf);
68     ::LocalFree( lpMsgBuf ); // free the buffer
69     while ( str.size()
70       && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
71         str.erase( str.size()-1 );
72 # else
73     str += std::strerror( errno );
74 # endif
75     return str;
76   }
77
78   struct ec_xlate { int sys_ec; fs::error_code ec; };
79   const ec_xlate ec_table[] =
80   {
81 #     ifdef BOOST_WINDOWS
82     { ERROR_ACCESS_DENIED, fs::security_error },
83     { ERROR_INVALID_ACCESS, fs::security_error },
84     { ERROR_SHARING_VIOLATION, fs::security_error },
85     { ERROR_LOCK_VIOLATION, fs::security_error },
86     { ERROR_LOCKED, fs::security_error },
87     { ERROR_NOACCESS, fs::security_error },
88     { ERROR_WRITE_PROTECT, fs::read_only_error },
89     { ERROR_NOT_READY, fs::io_error },
90     { ERROR_SEEK, fs::io_error },
91     { ERROR_READ_FAULT, fs::io_error },
92     { ERROR_WRITE_FAULT, fs::io_error },
93     { ERROR_CANTOPEN, fs::io_error },
94     { ERROR_CANTREAD, fs::io_error },
95     { ERROR_CANTWRITE, fs::io_error },
96     { ERROR_DIRECTORY, fs::path_error },
97     { ERROR_INVALID_NAME, fs::path_error },
98     { ERROR_FILE_NOT_FOUND, fs::not_found_error },
99     { ERROR_PATH_NOT_FOUND, fs::not_found_error },
100     { ERROR_DEV_NOT_EXIST, fs::not_found_error },
101     { ERROR_DEVICE_IN_USE, fs::busy_error },
102     { ERROR_OPEN_FILES, fs::busy_error },
103     { ERROR_BUSY_DRIVE, fs::busy_error },
104     { ERROR_BUSY, fs::busy_error },
105     { ERROR_FILE_EXISTS, fs::already_exists_error },
106     { ERROR_ALREADY_EXISTS, fs::already_exists_error },
107     { ERROR_DIR_NOT_EMPTY, fs::not_empty_error },
108     { ERROR_HANDLE_DISK_FULL, fs::out_of_space_error },
109     { ERROR_DISK_FULL, fs::out_of_space_error },
110     { ERROR_OUTOFMEMORY, fs::out_of_memory_error },
111     { ERROR_NOT_ENOUGH_MEMORY, fs::out_of_memory_error },
112     { ERROR_TOO_MANY_OPEN_FILES, fs::out_of_resource_error }
113 #     else
114     { EACCES, fs::security_error },
115     { EROFS, fs::read_only_error },
116     { EIO, fs::io_error },
117     { ENAMETOOLONG, fs::path_error },
118     { ENOENT, fs::not_found_error },
119     { ENOTDIR, fs::not_directory_error },
120     { EAGAIN, fs::busy_error },
121     { EBUSY, fs::busy_error },
122     { ETXTBSY, fs::busy_error },
123     { EEXIST, fs::already_exists_error },
124     { ENOTEMPTY, fs::not_empty_error },
125     { EISDIR, fs::is_directory_error },
126     { ENOSPC, fs::out_of_space_error },
127     { ENOMEM, fs::out_of_memory_error },
128     { EMFILE, fs::out_of_resource_error }
129 #     endif
130   };
131
132   fs::error_code lookup_error( int sys_err_code )
133   {
134     for ( const ec_xlate * cur = &ec_table[0];
135       cur != ec_table
136         + sizeof(ec_table)/sizeof(ec_xlate); ++cur )
137     {
138       if ( sys_err_code == cur->sys_ec ) return cur->ec;
139     }
140     return fs::system_error; // general system error code
141   }
142
143   // These helper functions work for POSIX and Windows. For systems where
144   // path->native_file_string() != path->native_directory_string(), more
145   // care would be required to get the right form for the function involved.
146
147   std::string other_error_prep(
148     const std::string & who,
149     const std::string & message )
150   {
151     return who + ": " + message;
152   }
153
154   std::string other_error_prep(
155     const std::string & who,
156     const fs::path & path1,
157     const std::string & message )
158   {
159     return who + ": \"" + path1.native_file_string() + "\": " + message;
160   }
161
162   std::string system_error_prep(
163     const std::string & who,
164     const fs::path & path1,
165     int sys_err_code )
166   {
167     return who + ": \"" + path1.native_file_string() + "\": "
168       + system_message( sys_err_code );
169   }
170
171   std::string system_error_prep(
172     const std::string & who,
173     const fs::path & path1,
174     const fs::path & path2,
175     int sys_err_code )
176   {
177     return who + ": \"" + path1.native_file_string()
178       + "\", \"" + path2.native_file_string() + "\": "
179       + system_message( sys_err_code );
180   }
181
182 } // unnamed namespace
183
184 namespace boost
185 {
186   namespace filesystem
187   {
188
189 //  filesystem_error implementation  -----------------------------------------//
190
191     filesystem_error::filesystem_error(
192       const std::string & who,
193       const std::string & message )
194       : std::runtime_error(
195           other_error_prep( who, message ).c_str() ),
196         m_sys_err(0), m_err(other_error), m_who(who)
197     {}
198  
199     filesystem_error::filesystem_error(
200       const std::string & who,
201       const path & path1,
202       const std::string & message )
203       : std::runtime_error(
204           other_error_prep( who, path1, message ).c_str() ),
205         m_sys_err(0), m_err(other_error), m_who(who), m_path1(path1)
206     {}
207  
208     filesystem_error::filesystem_error(
209       const std::string & who,
210       const path & path1,
211       int sys_err_code )
212       : std::runtime_error(
213           system_error_prep( who, path1, sys_err_code ).c_str() ),
214         m_sys_err(sys_err_code), m_err(lookup_error(sys_err_code)),
215         m_who(who), m_path1(path1)
216     {}
217
218     filesystem_error::filesystem_error(
219       const std::string & who,
220       const path & path1,
221       const path & path2,
222       int sys_err_code )
223       : std::runtime_error(
224           system_error_prep( who, path1, path2, sys_err_code ).c_str() ),
225         m_sys_err(sys_err_code), m_err(lookup_error(sys_err_code)),
226         m_who(who), m_path1(path1), m_path2(path2)
227     {}
228
229     filesystem_error::~filesystem_error() throw()
230     {
231     }
232
233     namespace detail
234     {
235       int system_error_code() // artifact of POSIX and WINDOWS error reporting
236       {
237   #   ifdef BOOST_WINDOWS
238         return ::GetLastError();
239   #   else
240         return errno; // GCC 3.1 won't accept ::errno
241   #   endif
242       }
243     } // namespace detail
244   } // namespace filesystem
245 } // namespace boost
246