diff --git a/utils/KillTheDoctor/system_error.h b/include/llvm/System/system_error.h similarity index 88% rename from utils/KillTheDoctor/system_error.h rename to include/llvm/System/system_error.h index 55faa1baeff..db89efeedb6 100644 --- a/utils/KillTheDoctor/system_error.h +++ b/include/llvm/System/system_error.h @@ -7,7 +7,10 @@ // //===----------------------------------------------------------------------===// // -// This was lifted from libc++ and modified for C++03. +// This was lifted from libc++ and modified for C++03. This is called +// system_error even though it does not define that class because that's what +// it's called in C++0x. We don't define system_error because it is only used +// for exception handling, which we don't use in LLVM. // //===----------------------------------------------------------------------===// @@ -224,6 +227,8 @@ template <> struct hash; #include #include +// This must be here instead of a .inc file because it is used in the definition +// of the enum values below. #ifdef LLVM_ON_WIN32 // VS 2008 needs this for some of the defines below. # include @@ -691,7 +696,7 @@ inline error_condition make_error_condition(errc _e) { inline bool operator<(const error_condition& _x, const error_condition& _y) { return _x.category() < _y.category() - || _x.category() == _y.category() && _x.value() < _y.value(); + || (_x.category() == _y.category() && _x.value() < _y.value()); } // error_code @@ -750,7 +755,7 @@ inline error_code make_error_code(errc _e) { inline bool operator<(const error_code& _x, const error_code& _y) { return _x.category() < _y.category() - || _x.category() == _y.category() && _x.value() < _y.value(); + || (_x.category() == _y.category() && _x.value() < _y.value()); } inline bool operator==(const error_code& _x, const error_code& _y) { @@ -788,97 +793,73 @@ inline bool operator!=(const error_condition& _x, const error_condition& _y) { // system_error -class system_error : public std::runtime_error { - error_code _ec_; -public: - system_error(error_code _ec, const std::string& _what_arg); - system_error(error_code _ec, const char* _what_arg); - system_error(error_code _ec); - system_error(int _ev, const error_category& _ecat, - const std::string& _what_arg); - system_error(int _ev, const error_category& _ecat, const char* _what_arg); - system_error(int _ev, const error_category& _ecat); - ~system_error() throw(); - - const error_code& code() const throw() {return _ec_;} - -private: - static std::string _init(const error_code&, std::string); -}; - -void _throw_system_error(int ev, const char* what_arg); - } // end namespace llvm +// This needs to stay here for KillTheDoctor. #ifdef LLVM_ON_WIN32 #include #include namespace llvm { -// To construct an error_code after a API error: +// To construct an error_code after an API error: // // error_code( ::GetLastError(), system_category() ) struct windows_error { enum _ { success = 0, // These names and values are based on Windows winerror.h - invalid_function = ERROR_INVALID_FUNCTION, - file_not_found = ERROR_FILE_NOT_FOUND, - path_not_found = ERROR_PATH_NOT_FOUND, - too_many_open_files = ERROR_TOO_MANY_OPEN_FILES, - access_denied = ERROR_ACCESS_DENIED, - invalid_handle = ERROR_INVALID_HANDLE, - arena_trashed = ERROR_ARENA_TRASHED, - not_enough_memory = ERROR_NOT_ENOUGH_MEMORY, - invalid_block = ERROR_INVALID_BLOCK, - bad_environment = ERROR_BAD_ENVIRONMENT, - bad_format = ERROR_BAD_FORMAT, - invalid_access = ERROR_INVALID_ACCESS, - outofmemory = ERROR_OUTOFMEMORY, - invalid_drive = ERROR_INVALID_DRIVE, - current_directory = ERROR_CURRENT_DIRECTORY, - not_same_device = ERROR_NOT_SAME_DEVICE, - no_more_files = ERROR_NO_MORE_FILES, - write_protect = ERROR_WRITE_PROTECT, - bad_unit = ERROR_BAD_UNIT, - not_ready = ERROR_NOT_READY, - bad_command = ERROR_BAD_COMMAND, - crc = ERROR_CRC, - bad_length = ERROR_BAD_LENGTH, - seek = ERROR_SEEK, - not_dos_disk = ERROR_NOT_DOS_DISK, - sector_not_found = ERROR_SECTOR_NOT_FOUND, - out_of_paper = ERROR_OUT_OF_PAPER, - write_fault = ERROR_WRITE_FAULT, - read_fault = ERROR_READ_FAULT, - gen_failure = ERROR_GEN_FAILURE, - sharing_violation = ERROR_SHARING_VIOLATION, - lock_violation = ERROR_LOCK_VIOLATION, - wrong_disk = ERROR_WRONG_DISK, + // This is not a complete list. + invalid_function = ERROR_INVALID_FUNCTION, + file_not_found = ERROR_FILE_NOT_FOUND, + path_not_found = ERROR_PATH_NOT_FOUND, + too_many_open_files = ERROR_TOO_MANY_OPEN_FILES, + access_denied = ERROR_ACCESS_DENIED, + invalid_handle = ERROR_INVALID_HANDLE, + arena_trashed = ERROR_ARENA_TRASHED, + not_enough_memory = ERROR_NOT_ENOUGH_MEMORY, + invalid_block = ERROR_INVALID_BLOCK, + bad_environment = ERROR_BAD_ENVIRONMENT, + bad_format = ERROR_BAD_FORMAT, + invalid_access = ERROR_INVALID_ACCESS, + outofmemory = ERROR_OUTOFMEMORY, + invalid_drive = ERROR_INVALID_DRIVE, + current_directory = ERROR_CURRENT_DIRECTORY, + not_same_device = ERROR_NOT_SAME_DEVICE, + no_more_files = ERROR_NO_MORE_FILES, + write_protect = ERROR_WRITE_PROTECT, + bad_unit = ERROR_BAD_UNIT, + not_ready = ERROR_NOT_READY, + bad_command = ERROR_BAD_COMMAND, + crc = ERROR_CRC, + bad_length = ERROR_BAD_LENGTH, + seek = ERROR_SEEK, + not_dos_disk = ERROR_NOT_DOS_DISK, + sector_not_found = ERROR_SECTOR_NOT_FOUND, + out_of_paper = ERROR_OUT_OF_PAPER, + write_fault = ERROR_WRITE_FAULT, + read_fault = ERROR_READ_FAULT, + gen_failure = ERROR_GEN_FAILURE, + sharing_violation = ERROR_SHARING_VIOLATION, + lock_violation = ERROR_LOCK_VIOLATION, + wrong_disk = ERROR_WRONG_DISK, sharing_buffer_exceeded = ERROR_SHARING_BUFFER_EXCEEDED, - handle_eof = ERROR_HANDLE_EOF, - handle_disk_full= ERROR_HANDLE_DISK_FULL, - rem_not_list = ERROR_REM_NOT_LIST, - dup_name = ERROR_DUP_NAME, - bad_net_path = ERROR_BAD_NETPATH, - network_busy = ERROR_NETWORK_BUSY, - // ... - file_exists = ERROR_FILE_EXISTS, - cannot_make = ERROR_CANNOT_MAKE, - // ... - broken_pipe = ERROR_BROKEN_PIPE, - open_failed = ERROR_OPEN_FAILED, - buffer_overflow = ERROR_BUFFER_OVERFLOW, - disk_full= ERROR_DISK_FULL, - // ... - lock_failed = ERROR_LOCK_FAILED, - busy = ERROR_BUSY, - cancel_violation = ERROR_CANCEL_VIOLATION, - already_exists = ERROR_ALREADY_EXISTS - // ... - - // TODO: add more Windows errors + handle_eof = ERROR_HANDLE_EOF, + handle_disk_full = ERROR_HANDLE_DISK_FULL, + rem_not_list = ERROR_REM_NOT_LIST, + dup_name = ERROR_DUP_NAME, + bad_net_path = ERROR_BAD_NETPATH, + network_busy = ERROR_NETWORK_BUSY, + file_exists = ERROR_FILE_EXISTS, + cannot_make = ERROR_CANNOT_MAKE, + broken_pipe = ERROR_BROKEN_PIPE, + open_failed = ERROR_OPEN_FAILED, + buffer_overflow = ERROR_BUFFER_OVERFLOW, + disk_full = ERROR_DISK_FULL, + lock_failed = ERROR_LOCK_FAILED, + busy = ERROR_BUSY, + cancel_violation = ERROR_CANCEL_VIOLATION, + already_exists = ERROR_ALREADY_EXISTS }; _ v_; diff --git a/lib/System/CMakeLists.txt b/lib/System/CMakeLists.txt index ac2830e80a0..16612ad88f6 100644 --- a/lib/System/CMakeLists.txt +++ b/lib/System/CMakeLists.txt @@ -19,6 +19,7 @@ add_llvm_library(LLVMSystem RWMutex.cpp SearchForAddressOfSpecialSymbol.cpp Signals.cpp + system_error.cpp ThreadLocal.cpp Threading.cpp TimeValue.cpp @@ -32,6 +33,7 @@ add_llvm_library(LLVMSystem Unix/Program.inc Unix/RWMutex.inc Unix/Signals.inc + Unix/system_error.inc Unix/ThreadLocal.inc Unix/TimeValue.inc Win32/Alarm.inc @@ -44,6 +46,7 @@ add_llvm_library(LLVMSystem Win32/Program.inc Win32/RWMutex.inc Win32/Signals.inc + Win32/system_error.inc Win32/ThreadLocal.inc Win32/TimeValue.inc ) diff --git a/lib/System/Unix/system_error.inc b/lib/System/Unix/system_error.inc new file mode 100644 index 00000000000..a382214877f --- /dev/null +++ b/lib/System/Unix/system_error.inc @@ -0,0 +1,34 @@ +//===- llvm/System/Unix/system_error.inc - Unix error_code ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the Unix specific implementation of the error_code +// and error_condition classes. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +//=== WARNING: Implementation here must contain only generic UNIX code that +//=== is guaranteed to work on *all* UNIX variants. +//===----------------------------------------------------------------------===// + +using namespace llvm; + +std::string +_system_error_category::message(int ev) const { + return _do_message::message(ev); +} + +error_condition +_system_error_category::default_error_condition(int ev) const { +#ifdef ELAST + if (ev > ELAST) + return error_condition(ev, system_category()); +#endif // ELAST + return error_condition(ev, generic_category()); +} diff --git a/lib/System/Win32/system_error.inc b/lib/System/Win32/system_error.inc new file mode 100644 index 00000000000..db025828996 --- /dev/null +++ b/lib/System/Win32/system_error.inc @@ -0,0 +1,140 @@ +//===- llvm/System/Win32/system_error.inc - Windows error_code --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the Windows specific implementation of the error_code +// and error_condition classes. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +//=== WARNING: Implementation here must contain only generic Windows code that +//=== is guaranteed to work on *all* Windows variants. +//===----------------------------------------------------------------------===// + +#include +#include + +using namespace llvm; + +std::string +_system_error_category::message(int ev) const { + LPVOID lpMsgBuf = 0; + DWORD retval = ::FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + ev, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPSTR) &lpMsgBuf, + 0, + NULL); + if (retval == 0) { + ::LocalFree(lpMsgBuf); + return std::string("Unknown error"); + } + + std::string str( static_cast(lpMsgBuf) ); + ::LocalFree(lpMsgBuf); + + while (str.size() + && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r')) + str.erase( str.size()-1 ); + if (str.size() && str[str.size()-1] == '.') + str.erase( str.size()-1 ); + return str; +} + +// I'd rather not double the line count of the following. +#define MAP_ERR_TO_COND(x, y) case x: return make_error_condition(errc::y) + +error_condition +_system_error_category::default_error_condition(int ev) const { + switch (ev) { + MAP_ERR_TO_COND(0, success); + // Windows system -> posix_errno decode table ---------------------------// + // see WinError.h comments for descriptions of errors + MAP_ERR_TO_COND(ERROR_ACCESS_DENIED, permission_denied); + MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS, file_exists); + MAP_ERR_TO_COND(ERROR_BAD_UNIT, no_such_device); + MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW, filename_too_long); + MAP_ERR_TO_COND(ERROR_BUSY, device_or_resource_busy); + MAP_ERR_TO_COND(ERROR_BUSY_DRIVE, device_or_resource_busy); + MAP_ERR_TO_COND(ERROR_CANNOT_MAKE, permission_denied); + MAP_ERR_TO_COND(ERROR_CANTOPEN, io_error); + MAP_ERR_TO_COND(ERROR_CANTREAD, io_error); + MAP_ERR_TO_COND(ERROR_CANTWRITE, io_error); + MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY, permission_denied); + MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST, no_such_device); + MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE, device_or_resource_busy); + MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY, directory_not_empty); + MAP_ERR_TO_COND(ERROR_DIRECTORY, invalid_argument); + MAP_ERR_TO_COND(ERROR_DISK_FULL, no_space_on_device); + MAP_ERR_TO_COND(ERROR_FILE_EXISTS, file_exists); + MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND, no_such_file_or_directory); + MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL, no_space_on_device); + MAP_ERR_TO_COND(ERROR_INVALID_ACCESS, permission_denied); + MAP_ERR_TO_COND(ERROR_INVALID_DRIVE, no_such_device); + MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION, function_not_supported); + MAP_ERR_TO_COND(ERROR_INVALID_HANDLE, invalid_argument); + MAP_ERR_TO_COND(ERROR_INVALID_NAME, invalid_argument); + MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION, no_lock_available); + MAP_ERR_TO_COND(ERROR_LOCKED, no_lock_available); + MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK, invalid_argument); + MAP_ERR_TO_COND(ERROR_NOACCESS, permission_denied); + MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY, not_enough_memory); + MAP_ERR_TO_COND(ERROR_NOT_READY, resource_unavailable_try_again); + MAP_ERR_TO_COND(ERROR_NOT_SAME_DEVICE, cross_device_link); + MAP_ERR_TO_COND(ERROR_OPEN_FAILED, io_error); + MAP_ERR_TO_COND(ERROR_OPEN_FILES, device_or_resource_busy); + MAP_ERR_TO_COND(ERROR_OPERATION_ABORTED, operation_canceled); + MAP_ERR_TO_COND(ERROR_OUTOFMEMORY, not_enough_memory); + MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND, no_such_file_or_directory); + MAP_ERR_TO_COND(ERROR_READ_FAULT, io_error); + MAP_ERR_TO_COND(ERROR_RETRY, resource_unavailable_try_again); + MAP_ERR_TO_COND(ERROR_SEEK, io_error); + MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION, permission_denied); + MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open); + MAP_ERR_TO_COND(ERROR_WRITE_FAULT, io_error); + MAP_ERR_TO_COND(ERROR_WRITE_PROTECT, permission_denied); + MAP_ERR_TO_COND(ERROR_SEM_TIMEOUT, timed_out); + MAP_ERR_TO_COND(WSAEACCES, permission_denied); + MAP_ERR_TO_COND(WSAEADDRINUSE, address_in_use); + MAP_ERR_TO_COND(WSAEADDRNOTAVAIL, address_not_available); + MAP_ERR_TO_COND(WSAEAFNOSUPPORT, address_family_not_supported); + MAP_ERR_TO_COND(WSAEALREADY, connection_already_in_progress); + MAP_ERR_TO_COND(WSAEBADF, bad_file_descriptor); + MAP_ERR_TO_COND(WSAECONNABORTED, connection_aborted); + MAP_ERR_TO_COND(WSAECONNREFUSED, connection_refused); + MAP_ERR_TO_COND(WSAECONNRESET, connection_reset); + MAP_ERR_TO_COND(WSAEDESTADDRREQ, destination_address_required); + MAP_ERR_TO_COND(WSAEFAULT, bad_address); + MAP_ERR_TO_COND(WSAEHOSTUNREACH, host_unreachable); + MAP_ERR_TO_COND(WSAEINPROGRESS, operation_in_progress); + MAP_ERR_TO_COND(WSAEINTR, interrupted); + MAP_ERR_TO_COND(WSAEINVAL, invalid_argument); + MAP_ERR_TO_COND(WSAEISCONN, already_connected); + MAP_ERR_TO_COND(WSAEMFILE, too_many_files_open); + MAP_ERR_TO_COND(WSAEMSGSIZE, message_size); + MAP_ERR_TO_COND(WSAENAMETOOLONG, filename_too_long); + MAP_ERR_TO_COND(WSAENETDOWN, network_down); + MAP_ERR_TO_COND(WSAENETRESET, network_reset); + MAP_ERR_TO_COND(WSAENETUNREACH, network_unreachable); + MAP_ERR_TO_COND(WSAENOBUFS, no_buffer_space); + MAP_ERR_TO_COND(WSAENOPROTOOPT, no_protocol_option); + MAP_ERR_TO_COND(WSAENOTCONN, not_connected); + MAP_ERR_TO_COND(WSAENOTSOCK, not_a_socket); + MAP_ERR_TO_COND(WSAEOPNOTSUPP, operation_not_supported); + MAP_ERR_TO_COND(WSAEPROTONOSUPPORT, protocol_not_supported); + MAP_ERR_TO_COND(WSAEPROTOTYPE, wrong_protocol_type); + MAP_ERR_TO_COND(WSAETIMEDOUT, timed_out); + MAP_ERR_TO_COND(WSAEWOULDBLOCK, operation_would_block); + default: return error_condition(ev, system_category()); + } +} diff --git a/lib/System/system_error.cpp b/lib/System/system_error.cpp new file mode 100644 index 00000000000..e7de85255e1 --- /dev/null +++ b/lib/System/system_error.cpp @@ -0,0 +1,121 @@ +//===---------------------- system_error.cpp ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This was lifted from libc++ and modified for C++03. +// +//===----------------------------------------------------------------------===// + +#include "llvm/System/system_error.h" +#include "llvm/System/Errno.h" +#include +#include + +namespace llvm { + +// class error_category + +error_category::error_category() { +} + +error_category::~error_category() { +} + +error_condition +error_category::default_error_condition(int ev) const { + return error_condition(ev, *this); +} + +bool +error_category::equivalent(int code, const error_condition& condition) const { + return default_error_condition(code) == condition; +} + +bool +error_category::equivalent(const error_code& code, int condition) const { + return *this == code.category() && code.value() == condition; +} + +std::string +_do_message::message(int ev) const { + return std::string(sys::StrError(ev)); +} + +class _generic_error_category : public _do_message { +public: + virtual const char* name() const; + virtual std::string message(int ev) const; +}; + +const char* +_generic_error_category::name() const { + return "generic"; +} + +std::string +_generic_error_category::message(int ev) const { +#ifdef ELAST + if (ev > ELAST) + return std::string("unspecified generic_category error"); +#endif // ELAST + return _do_message::message(ev); +} + +const error_category& +generic_category() { + static _generic_error_category s; + return s; +} + +class _system_error_category : public _do_message { +public: + virtual const char* name() const; + virtual std::string message(int ev) const; + virtual error_condition default_error_condition(int ev) const; +}; + +const char* +_system_error_category::name() const { + return "system"; +} + +// std::string _system_error_category::message(int ev) const { +// Is in Platform/system_error.inc + +// error_condition _system_error_category::default_error_condition(int ev) const +// Is in Platform/system_error.inc + +const error_category& +system_category() { + static _system_error_category s; + return s; +} + +// error_condition + +std::string +error_condition::message() const { + return _cat_->message(_val_); +} + +// error_code + +std::string +error_code::message() const { + return _cat_->message(_val_); +} + +} // end namespace llvm + +// Include the truly platform-specific parts of this class. +#if defined(LLVM_ON_UNIX) +#include "Unix/system_error.inc" +#endif +#if defined(LLVM_ON_WIN32) +#include "Win32/system_error.inc" +#endif diff --git a/utils/KillTheDoctor/CMakeLists.txt b/utils/KillTheDoctor/CMakeLists.txt index 32e481cbead..fc6fa9b508d 100644 --- a/utils/KillTheDoctor/CMakeLists.txt +++ b/utils/KillTheDoctor/CMakeLists.txt @@ -1,6 +1,5 @@ add_executable(KillTheDoctor KillTheDoctor.cpp - system_error.cpp ) target_link_libraries(KillTheDoctor LLVMSupport LLVMSystem) diff --git a/utils/KillTheDoctor/KillTheDoctor.cpp b/utils/KillTheDoctor/KillTheDoctor.cpp index c0bf437a72e..28b1c0ad38a 100644 --- a/utils/KillTheDoctor/KillTheDoctor.cpp +++ b/utils/KillTheDoctor/KillTheDoctor.cpp @@ -42,7 +42,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/type_traits.h" #include "llvm/System/Signals.h" -#include "system_error.h" +#include "llvm/System/system_error.h" #include #include #include diff --git a/utils/KillTheDoctor/system_error.cpp b/utils/KillTheDoctor/system_error.cpp deleted file mode 100644 index 0e78fb379ec..00000000000 --- a/utils/KillTheDoctor/system_error.cpp +++ /dev/null @@ -1,287 +0,0 @@ -//===---------------------- system_error.cpp ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This was lifted from libc++ and modified for C++03. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" -#include "system_error.h" -#include -#include - -namespace llvm { - -// class error_category - -error_category::error_category() { -} - -error_category::~error_category() { -} - -error_condition -error_category::default_error_condition(int ev) const { - return error_condition(ev, *this); -} - -bool -error_category::equivalent(int code, const error_condition& condition) const { - return default_error_condition(code) == condition; -} - -bool -error_category::equivalent(const error_code& code, int condition) const { - return *this == code.category() && code.value() == condition; -} - -std::string -_do_message::message(int ev) const { - return std::string(std::strerror(ev)); -} - -class _generic_error_category : public _do_message { -public: - virtual const char* name() const; - virtual std::string message(int ev) const; -}; - -const char* -_generic_error_category::name() const { - return "generic"; -} - -std::string -_generic_error_category::message(int ev) const { -#ifdef ELAST - if (ev > ELAST) - return std::string("unspecified generic_category error"); -#endif // ELAST - return _do_message::message(ev); -} - -const error_category& -generic_category() { - static _generic_error_category s; - return s; -} - -class _system_error_category : public _do_message { -public: - virtual const char* name() const; - virtual std::string message(int ev) const; - virtual error_condition default_error_condition(int ev) const; -}; - -const char* -_system_error_category::name() const { - return "system"; -} - -// std::string _system_error_category::message(int ev) const { -// Is in Platform/system_error.inc - -// error_condition _system_error_category::default_error_condition(int ev) const -// Is in Platform/system_error.inc - -const error_category& -system_category() { - static _system_error_category s; - return s; -} - -// error_condition - -std::string -error_condition::message() const { - return _cat_->message(_val_); -} - -// error_code - -std::string -error_code::message() const { - return _cat_->message(_val_); -} - -// system_error - -std::string -system_error::_init(const error_code& ec, std::string what_arg) { - if (ec) - { - if (!what_arg.empty()) - what_arg += ": "; - what_arg += ec.message(); - } - return what_arg; -} - -system_error::system_error(error_code ec, const std::string& what_arg) - : runtime_error(_init(ec, what_arg)), _ec_(ec) { -} - -system_error::system_error(error_code ec, const char* what_arg) - : runtime_error(_init(ec, what_arg)), _ec_(ec) { -} - -system_error::system_error(error_code ec) - : runtime_error(_init(ec, "")), _ec_(ec) { -} - -system_error::system_error(int ev, const error_category& ecat, - const std::string& what_arg) - : runtime_error(_init(error_code(ev, ecat), what_arg)) - , _ec_(error_code(ev, ecat)) { -} - -system_error::system_error(int ev, const error_category& ecat, - const char* what_arg) - : runtime_error(_init(error_code(ev, ecat), what_arg)) - , _ec_(error_code(ev, ecat)) { -} - -system_error::system_error(int ev, const error_category& ecat) - : runtime_error(_init(error_code(ev, ecat), "")), _ec_(error_code(ev, ecat)) { -} - -system_error::~system_error() throw() { -} - -void -_throw_system_error(int ev, const char* what_arg) { - throw system_error(error_code(ev, system_category()), what_arg); -} - -} // end namespace llvm - -#ifdef LLVM_ON_WIN32 -#include -#include - -namespace llvm { - -std::string -_system_error_category::message(int ev) const { - LPVOID lpMsgBuf = 0; - DWORD retval = ::FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - ev, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPSTR) &lpMsgBuf, - 0, - NULL); - if (retval == 0) { - ::LocalFree(lpMsgBuf); - return std::string("Unknown error"); - } - - std::string str( static_cast(lpMsgBuf) ); - ::LocalFree(lpMsgBuf); - - while (str.size() - && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r')) - str.erase( str.size()-1 ); - if (str.size() && str[str.size()-1] == '.') - str.erase( str.size()-1 ); - return str; -} - -error_condition -_system_error_category::default_error_condition(int ev) const { - switch (ev) - { - case 0: return make_error_condition(errc::success); - // Windows system -> posix_errno decode table ---------------------------// - // see WinError.h comments for descriptions of errors - case ERROR_ACCESS_DENIED: return make_error_condition(errc::permission_denied); - case ERROR_ALREADY_EXISTS: return make_error_condition(errc::file_exists); - case ERROR_BAD_UNIT: return make_error_condition(errc::no_such_device); - case ERROR_BUFFER_OVERFLOW: return make_error_condition(errc::filename_too_long); - case ERROR_BUSY: return make_error_condition(errc::device_or_resource_busy); - case ERROR_BUSY_DRIVE: return make_error_condition(errc::device_or_resource_busy); - case ERROR_CANNOT_MAKE: return make_error_condition(errc::permission_denied); - case ERROR_CANTOPEN: return make_error_condition(errc::io_error); - case ERROR_CANTREAD: return make_error_condition(errc::io_error); - case ERROR_CANTWRITE: return make_error_condition(errc::io_error); - case ERROR_CURRENT_DIRECTORY: return make_error_condition(errc::permission_denied); - case ERROR_DEV_NOT_EXIST: return make_error_condition(errc::no_such_device); - case ERROR_DEVICE_IN_USE: return make_error_condition(errc::device_or_resource_busy); - case ERROR_DIR_NOT_EMPTY: return make_error_condition(errc::directory_not_empty); - case ERROR_DIRECTORY: return make_error_condition(errc::invalid_argument); - case ERROR_DISK_FULL: return make_error_condition(errc::no_space_on_device); - case ERROR_FILE_EXISTS: return make_error_condition(errc::file_exists); - case ERROR_FILE_NOT_FOUND: return make_error_condition(errc::no_such_file_or_directory); - case ERROR_HANDLE_DISK_FULL: return make_error_condition(errc::no_space_on_device); - case ERROR_INVALID_ACCESS: return make_error_condition(errc::permission_denied); - case ERROR_INVALID_DRIVE: return make_error_condition(errc::no_such_device); - case ERROR_INVALID_FUNCTION: return make_error_condition(errc::function_not_supported); - case ERROR_INVALID_HANDLE: return make_error_condition(errc::invalid_argument); - case ERROR_INVALID_NAME: return make_error_condition(errc::invalid_argument); - case ERROR_LOCK_VIOLATION: return make_error_condition(errc::no_lock_available); - case ERROR_LOCKED: return make_error_condition(errc::no_lock_available); - case ERROR_NEGATIVE_SEEK: return make_error_condition(errc::invalid_argument); - case ERROR_NOACCESS: return make_error_condition(errc::permission_denied); - case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition(errc::not_enough_memory); - case ERROR_NOT_READY: return make_error_condition(errc::resource_unavailable_try_again); - case ERROR_NOT_SAME_DEVICE: return make_error_condition(errc::cross_device_link); - case ERROR_OPEN_FAILED: return make_error_condition(errc::io_error); - case ERROR_OPEN_FILES: return make_error_condition(errc::device_or_resource_busy); - case ERROR_OPERATION_ABORTED: return make_error_condition(errc::operation_canceled); - case ERROR_OUTOFMEMORY: return make_error_condition(errc::not_enough_memory); - case ERROR_PATH_NOT_FOUND: return make_error_condition(errc::no_such_file_or_directory); - case ERROR_READ_FAULT: return make_error_condition(errc::io_error); - case ERROR_RETRY: return make_error_condition(errc::resource_unavailable_try_again); - case ERROR_SEEK: return make_error_condition(errc::io_error); - case ERROR_SHARING_VIOLATION: return make_error_condition(errc::permission_denied); - case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition(errc::too_many_files_open); - case ERROR_WRITE_FAULT: return make_error_condition(errc::io_error); - case ERROR_WRITE_PROTECT: return make_error_condition(errc::permission_denied); - case ERROR_SEM_TIMEOUT: return make_error_condition(errc::timed_out); - case WSAEACCES: return make_error_condition(errc::permission_denied); - case WSAEADDRINUSE: return make_error_condition(errc::address_in_use); - case WSAEADDRNOTAVAIL: return make_error_condition(errc::address_not_available); - case WSAEAFNOSUPPORT: return make_error_condition(errc::address_family_not_supported); - case WSAEALREADY: return make_error_condition(errc::connection_already_in_progress); - case WSAEBADF: return make_error_condition(errc::bad_file_descriptor); - case WSAECONNABORTED: return make_error_condition(errc::connection_aborted); - case WSAECONNREFUSED: return make_error_condition(errc::connection_refused); - case WSAECONNRESET: return make_error_condition(errc::connection_reset); - case WSAEDESTADDRREQ: return make_error_condition(errc::destination_address_required); - case WSAEFAULT: return make_error_condition(errc::bad_address); - case WSAEHOSTUNREACH: return make_error_condition(errc::host_unreachable); - case WSAEINPROGRESS: return make_error_condition(errc::operation_in_progress); - case WSAEINTR: return make_error_condition(errc::interrupted); - case WSAEINVAL: return make_error_condition(errc::invalid_argument); - case WSAEISCONN: return make_error_condition(errc::already_connected); - case WSAEMFILE: return make_error_condition(errc::too_many_files_open); - case WSAEMSGSIZE: return make_error_condition(errc::message_size); - case WSAENAMETOOLONG: return make_error_condition(errc::filename_too_long); - case WSAENETDOWN: return make_error_condition(errc::network_down); - case WSAENETRESET: return make_error_condition(errc::network_reset); - case WSAENETUNREACH: return make_error_condition(errc::network_unreachable); - case WSAENOBUFS: return make_error_condition(errc::no_buffer_space); - case WSAENOPROTOOPT: return make_error_condition(errc::no_protocol_option); - case WSAENOTCONN: return make_error_condition(errc::not_connected); - case WSAENOTSOCK: return make_error_condition(errc::not_a_socket); - case WSAEOPNOTSUPP: return make_error_condition(errc::operation_not_supported); - case WSAEPROTONOSUPPORT: return make_error_condition(errc::protocol_not_supported); - case WSAEPROTOTYPE: return make_error_condition(errc::wrong_protocol_type); - case WSAETIMEDOUT: return make_error_condition(errc::timed_out); - case WSAEWOULDBLOCK: return make_error_condition(errc::operation_would_block); - default: return error_condition(ev, system_category()); - } -} - -} // end namespace llvm - -#endif // LLVM_ON_WIN32