From 615d333787c1d8dc08df5e30c60ec20600a74b85 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 22 Mar 2017 00:36:27 +0300 Subject: Implement throw_generic_error() and throw_system_error() --- butl/utility.cxx | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'butl/utility.cxx') diff --git a/butl/utility.cxx b/butl/utility.cxx index 84c8a74..03045da 100644 --- a/butl/utility.cxx +++ b/butl/utility.cxx @@ -2,12 +2,20 @@ // copyright : Copyright (c) 2014-2017 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -#include - #include +#ifdef _WIN32 +# include +#endif + +#include +#include +#include + namespace butl { + using namespace std; + #ifndef __cpp_lib_uncaught_exceptions #ifdef __cpp_thread_local @@ -23,6 +31,39 @@ namespace butl #endif #endif + + [[noreturn]] void + throw_generic_error (int errno_code, const char* what) + { + if (what == nullptr) + throw system_error (errno_code, generic_category ()); + else + throw system_error (errno_code, generic_category (), what); + } + + [[noreturn]] void +#ifndef _WIN32 + throw_system_error (int system_code, int) + { + throw system_error (system_code, system_category ()); +#else + throw_system_error (int system_code, int fallback_errno_code) + { + // Here we work around MinGW libstdc++ that interprets Windows system error + // codes (for example those returned by GetLastError()) as errno codes. The + // resulting system_error description will have the following form: + // + // : + // + // Also note that the fallback-related description suffix is stripped by + // our custom operator<<(ostream, exception) for the common case (see + // below). + // + throw system_error (fallback_errno_code, + system_category (), + win32::error_msg (system_code)); +#endif + } } namespace std @@ -63,6 +104,16 @@ namespace std break; } + // Strip the suffix for system_error thrown by + // throw_system_error(system_code) on Windows. For example for the + // ERROR_INVALID_DATA error code the original description will be + // 'Invalid data. : Success' for MinGW libstdc++ and + // 'Invalid data. : Success.' for msvcrt. + // + if (n >= 11 && + string::traits_type::compare (s + n - 11, ". : Success", 11) == 0) + n -= 11; + // Lower-case the first letter if the beginning looks like a word (the // second character is the lower-case letter or space). // -- cgit v1.1