Replace FMT_THROW with FMT_ERROR
FMT_ERROR uses fmt::error_reporter_t, which enables user to customize error handler. This is especially useful when the exception is disabled. Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
578874033a
commit
b23f48f297
@ -326,7 +326,7 @@ inline std::tm localtime(std::time_t time) {
|
||||
};
|
||||
dispatcher lt(time);
|
||||
// Too big time values may be unsupported.
|
||||
if (!lt.run()) FMT_THROW(format_error("time_t value out of range"));
|
||||
if (!lt.run()) FMT_ERROR(Error_type::format_error, "time_t value out of range");
|
||||
return lt.tm_;
|
||||
}
|
||||
|
||||
@ -371,7 +371,7 @@ inline std::tm gmtime(std::time_t time) {
|
||||
};
|
||||
dispatcher gt(time);
|
||||
// Too big time values may be unsupported.
|
||||
if (!gt.run()) FMT_THROW(format_error("time_t value out of range"));
|
||||
if (!gt.run()) FMT_ERROR(Error_type::format_error, "time_t value out of range");
|
||||
return gt.tm_;
|
||||
}
|
||||
|
||||
@ -537,7 +537,9 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin,
|
||||
}
|
||||
if (begin != ptr) handler.on_text(begin, ptr);
|
||||
++ptr; // consume '%'
|
||||
if (ptr == end) FMT_THROW(format_error("invalid format"));
|
||||
if (ptr == end)
|
||||
FMT_ERROR(Error_type::format_error, "invalid format",
|
||||
basic_string_view<Char>(begin, static_cast<std::size_t>(end - begin)));
|
||||
c = *ptr++;
|
||||
switch (c) {
|
||||
case '%':
|
||||
@ -628,7 +630,9 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin,
|
||||
break;
|
||||
// Alternative representation:
|
||||
case 'E': {
|
||||
if (ptr == end) FMT_THROW(format_error("invalid format"));
|
||||
if (ptr == end)
|
||||
FMT_ERROR(Error_type::format_error, "invalid format",
|
||||
basic_string_view<Char>(begin, static_cast<std::size_t>(end - begin)));
|
||||
c = *ptr++;
|
||||
switch (c) {
|
||||
case 'c':
|
||||
@ -641,12 +645,15 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin,
|
||||
handler.on_loc_time(numeric_system::alternative);
|
||||
break;
|
||||
default:
|
||||
FMT_THROW(format_error("invalid format"));
|
||||
FMT_ERROR(Error_type::format_error, "invalid format",
|
||||
basic_string_view<Char>(begin, static_cast<std::size_t>(end - begin)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'O':
|
||||
if (ptr == end) FMT_THROW(format_error("invalid format"));
|
||||
if (ptr == end)
|
||||
FMT_ERROR(Error_type::format_error, "invalid format",
|
||||
basic_string_view<Char>(begin, static_cast<std::size_t>(end - begin)));
|
||||
c = *ptr++;
|
||||
switch (c) {
|
||||
case 'w':
|
||||
@ -668,11 +675,13 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin,
|
||||
handler.on_second(numeric_system::alternative);
|
||||
break;
|
||||
default:
|
||||
FMT_THROW(format_error("invalid format"));
|
||||
FMT_ERROR(Error_type::format_error, "invalid format",
|
||||
basic_string_view<Char>(begin, static_cast<std::size_t>(end - begin)));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FMT_THROW(format_error("invalid format"));
|
||||
FMT_ERROR(Error_type::format_error, "invalid format",
|
||||
basic_string_view<Char>(begin, static_cast<std::size_t>(end - begin)));
|
||||
}
|
||||
begin = ptr;
|
||||
}
|
||||
@ -681,7 +690,7 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin,
|
||||
}
|
||||
|
||||
struct chrono_format_checker {
|
||||
FMT_NORETURN void report_no_date() { FMT_THROW(format_error("no date")); }
|
||||
FMT_NORETURN void report_no_date() { FMT_ERROR(Error_type::format_error, "no date"); }
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
|
||||
@ -771,7 +780,7 @@ template <typename To, typename FromRep, typename FromPeriod>
|
||||
To fmt_safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from) {
|
||||
int ec;
|
||||
To to = safe_duration_cast::safe_duration_cast<To>(from, ec);
|
||||
if (ec) FMT_THROW(format_error("cannot format duration"));
|
||||
if (ec) FMT_ERROR(Error_type::format_error, "cannot format duration");
|
||||
return to;
|
||||
}
|
||||
#endif
|
||||
@ -1104,7 +1113,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
||||
return arg_ref_type(context.next_arg_id());
|
||||
}
|
||||
|
||||
void on_error(const char* msg) { FMT_THROW(format_error(msg)); }
|
||||
void on_error(const char* msg) { FMT_ERROR(Error_type::format_error, msg); }
|
||||
FMT_CONSTEXPR void on_fill(basic_string_view<Char> fill) {
|
||||
f.specs.fill = fill;
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ class text_style {
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
FMT_ERROR(Error_type::format_error, "can't OR a terminal color");
|
||||
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ class text_style {
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
FMT_ERROR(Error_type::format_error, "can't OR a terminal color");
|
||||
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
@ -321,7 +321,7 @@ class text_style {
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't AND a terminal color"));
|
||||
FMT_ERROR(Error_type::format_error, "can't AND a terminal color");
|
||||
foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
@ -330,7 +330,7 @@ class text_style {
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't AND a terminal color"));
|
||||
FMT_ERROR(Error_type::format_error, "can't AND a terminal color");
|
||||
background_color.value.rgb_color &= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
|
||||
@ -164,7 +164,7 @@ FMT_FUNC void report_error(format_func func, int error_code,
|
||||
inline void fwrite_fully(const void* ptr, size_t size, size_t count,
|
||||
FILE* stream) {
|
||||
size_t written = std::fwrite(ptr, size, count, stream);
|
||||
if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
|
||||
if (written < count) FMT_ERROR(Error_type::system_error, errno, "cannot write to file");
|
||||
}
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
@ -2627,7 +2627,7 @@ template <> struct formatter<detail::bigint> {
|
||||
|
||||
FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) {
|
||||
for_each_codepoint(s, [this](uint32_t cp, int error) {
|
||||
if (error != 0) FMT_THROW(std::runtime_error("invalid utf8"));
|
||||
if (error != 0) FMT_ERROR(Error_type::runtime_error, "invalid utf8");
|
||||
if (cp <= 0xFFFF) {
|
||||
buffer_.push_back(static_cast<wchar_t>(cp));
|
||||
} else {
|
||||
@ -2663,7 +2663,7 @@ FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
|
||||
}
|
||||
|
||||
FMT_FUNC void detail::error_handler::on_error(const char* message) {
|
||||
FMT_THROW(format_error(message));
|
||||
FMT_ERROR(Error_type::format_error, message);
|
||||
}
|
||||
|
||||
FMT_FUNC void report_system_error(int error_code,
|
||||
|
||||
@ -103,29 +103,53 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FMT_THROW
|
||||
# if FMT_EXCEPTIONS
|
||||
# if FMT_MSC_VER || FMT_NVCC
|
||||
#ifndef FMT_ERROR
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
template <typename Exception> inline void do_throw(const Exception& x) {
|
||||
// Silence unreachable code warnings in MSVC and NVCC because these
|
||||
// are nearly impossible to fix in a generic code.
|
||||
volatile bool b = true;
|
||||
if (b) throw x;
|
||||
}
|
||||
} // namespace detail
|
||||
enum class Error_type {
|
||||
format_error,
|
||||
system_error,
|
||||
runtime_error,
|
||||
# ifdef _WIN32
|
||||
windows_error,
|
||||
# endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Use error_reporter_t as a customization point.
|
||||
*/
|
||||
template <Error_type error_type, typename = void> struct error_reporter_t;
|
||||
|
||||
template <typename void_type> struct error_reporter_t<Error_type::format_error, void_type> {
|
||||
template <typename Char = char>
|
||||
FMT_NORETURN void operator () (int line, const char *func, const char *file, const char *msg,
|
||||
basic_string_view<Char> fmt = basic_string_view<Char>());
|
||||
};
|
||||
|
||||
template <typename void_type> struct error_reporter_t<Error_type::system_error, void_type> {
|
||||
template <typename ...Args>
|
||||
FMT_NORETURN void operator () (int line, const char *func, const char *file,
|
||||
int error_code, const char *msg,
|
||||
const Args&... args);
|
||||
};
|
||||
|
||||
template <typename void_type> struct error_reporter_t<Error_type::runtime_error, void_type> {
|
||||
FMT_NORETURN void operator () (int line, const char *func, const char *file, const char *msg);
|
||||
};
|
||||
|
||||
# ifdef __GNUC__
|
||||
# define FMT_ERROR(error_type, ...) \
|
||||
do { \
|
||||
::fmt::error_reporter_t<(error_type)> error_reporter; \
|
||||
error_reporter(__LINE__, __PRETTY_FUNCTION__, __FILE__, __VA_ARGS__); \
|
||||
} while (0)
|
||||
# else
|
||||
# define FMT_ERROR(error_type, ...) \
|
||||
do { \
|
||||
::fmt::error_reporter_t<(error_type)> error_reporter; \
|
||||
error_reporter(__LINE__, __FUNCTION__, __FILE__, __VA_ARGS__); \
|
||||
} while (0)
|
||||
# endif
|
||||
FMT_END_NAMESPACE
|
||||
# define FMT_THROW(x) detail::do_throw(x)
|
||||
# else
|
||||
# define FMT_THROW(x) throw x
|
||||
# endif
|
||||
# else
|
||||
# define FMT_THROW(x) \
|
||||
do { \
|
||||
FMT_ASSERT(false, (x).what()); \
|
||||
} while (false)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if FMT_EXCEPTIONS
|
||||
@ -940,7 +964,6 @@ class FMT_API format_error : public std::runtime_error {
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
using is_signed =
|
||||
std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
|
||||
@ -1324,7 +1347,7 @@ template <typename Char> struct fill_t {
|
||||
FMT_CONSTEXPR void operator=(basic_string_view<Char> s) {
|
||||
auto size = s.size();
|
||||
if (size > max_size) {
|
||||
FMT_THROW(format_error("invalid fill"));
|
||||
FMT_ERROR(Error_type::format_error, "invalid fill");
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < size; ++i) data_[i] = s[i];
|
||||
@ -1928,7 +1951,7 @@ template <typename OutputIt, typename Char, typename UInt> struct int_writer {
|
||||
void on_chr() { out = write_char(out, static_cast<Char>(abs_value), specs); }
|
||||
|
||||
FMT_NORETURN void on_error() {
|
||||
FMT_THROW(format_error("invalid type specifier"));
|
||||
FMT_ERROR(Error_type::format_error, "invalid type specifier");
|
||||
}
|
||||
};
|
||||
|
||||
@ -2146,7 +2169,7 @@ OutputIt write(OutputIt out, T value, basic_format_specs<Char> specs,
|
||||
int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6;
|
||||
if (fspecs.format == float_format::exp) {
|
||||
if (precision == max_value<int>())
|
||||
FMT_THROW(format_error("number is too big"));
|
||||
FMT_ERROR(Error_type::format_error, "number is too big");
|
||||
else
|
||||
++precision;
|
||||
}
|
||||
@ -2282,7 +2305,7 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, Char value) {
|
||||
template <typename Char, typename OutputIt>
|
||||
FMT_CONSTEXPR OutputIt write(OutputIt out, const Char* value) {
|
||||
if (!value) {
|
||||
FMT_THROW(format_error("string pointer is null"));
|
||||
FMT_ERROR(Error_type::format_error, "string pointer is null");
|
||||
} else {
|
||||
auto length = std::char_traits<Char>::length(value);
|
||||
out = write(out, basic_string_view<Char>(value, length));
|
||||
@ -2442,7 +2465,7 @@ class arg_formatter_base {
|
||||
|
||||
void write(const Char* value) {
|
||||
if (!value) {
|
||||
FMT_THROW(format_error("string pointer is null"));
|
||||
FMT_ERROR(Error_type::format_error, "string pointer is null");
|
||||
} else {
|
||||
auto length = std::char_traits<char_type>::length(value);
|
||||
basic_string_view<char_type> sv(value, length);
|
||||
@ -3546,6 +3569,65 @@ FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
|
||||
FMT_API void report_system_error(int error_code,
|
||||
string_view message) FMT_NOEXCEPT;
|
||||
|
||||
/* Overload for format_error */
|
||||
template <typename void_type>
|
||||
template <typename Char>
|
||||
FMT_NORETURN void error_reporter_t<Error_type::format_error, void_type>::operator () (
|
||||
int line, const char *func, const char *file,
|
||||
const char *msg, basic_string_view<Char> fmt) {
|
||||
#if FMT_EXCEPTIONS
|
||||
static_cast<void>(line);
|
||||
static_cast<void>(func);
|
||||
static_cast<void>(file);
|
||||
static_cast<void>(fmt);
|
||||
|
||||
throw format_error(msg);
|
||||
#else
|
||||
if (fmt.size())
|
||||
std::fprintf(stderr, "%d of %s, %s failed to format %s: %s\n",
|
||||
line, func, file, fmt.data(), msg);
|
||||
else
|
||||
std::fprintf(stderr, "%d of %s, %s failed: %s\n",
|
||||
line, func, file, msg);
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Overload for system_error */
|
||||
template <typename void_type>
|
||||
template <typename ...Args>
|
||||
FMT_NORETURN void error_reporter_t<Error_type::system_error, void_type>::operator () (
|
||||
int line, const char *func, const char *file,
|
||||
int error_code, const char *msg, const Args&... args) {
|
||||
#if FMT_EXCEPTIONS
|
||||
static_cast<void>(line);
|
||||
static_cast<void>(func);
|
||||
static_cast<void>(file);
|
||||
|
||||
throw system_error(error_code, msg, args...);
|
||||
#else
|
||||
report_system_error(error_code, format(msg, args...));
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Overload for runtime_error */
|
||||
template <typename void_type>
|
||||
FMT_NORETURN void error_reporter_t<Error_type::runtime_error, void_type>::operator () (
|
||||
int line, const char *func, const char *file,
|
||||
const char *msg) {
|
||||
#if FMT_EXCEPTIONS
|
||||
static_cast<void>(line);
|
||||
static_cast<void>(func);
|
||||
static_cast<void>(file);
|
||||
|
||||
throw std::runtime_error(msg);
|
||||
#else
|
||||
std::fprintf(stderr, "Runtime error: %s\n", msg);
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Fast integer formatter. */
|
||||
class format_int {
|
||||
private:
|
||||
@ -4123,7 +4205,7 @@ void vprint(std::FILE* f, basic_string_view<Char> format_str,
|
||||
detail::vformat_to(buffer, format_str, args);
|
||||
buffer.push_back(L'\0');
|
||||
if (std::fputws(buffer.data(), f) == -1)
|
||||
FMT_THROW(system_error(errno, "cannot write to file"));
|
||||
FMT_ERROR(Error_type::system_error, errno, "cannot write to file");
|
||||
}
|
||||
|
||||
template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
|
||||
|
||||
@ -198,6 +198,25 @@ class windows_error : public system_error {
|
||||
// Can be used to report errors from destructors.
|
||||
FMT_API void report_windows_error(int error_code,
|
||||
string_view message) FMT_NOEXCEPT;
|
||||
|
||||
template <typename void_type> struct error_reporter_t<Error_type::windows_error, void_type> {
|
||||
template <typename... Args>
|
||||
FMT_NORETURN void operator () (int line, const char *func, const char *file,
|
||||
int error_code, const char *message,
|
||||
const Args&... args) {
|
||||
#if FMT_EXCEPTIONS
|
||||
static_cast<void>(line);
|
||||
static_cast<void>(func);
|
||||
static_cast<void>(file);
|
||||
|
||||
throw windows_error(error_code, message, args...);
|
||||
#else
|
||||
report_windows_error(error_code, format(message, args...));
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
// A buffered file.
|
||||
@ -469,7 +488,7 @@ class locale {
|
||||
# else
|
||||
locale_ = _create_locale(LC_NUMERIC, "C");
|
||||
# endif
|
||||
if (!locale_) FMT_THROW(system_error(errno, "cannot create locale"));
|
||||
if (!locale_) FMT_ERROR(Error_type::system_error, errno, "cannot create locale");
|
||||
}
|
||||
~locale() { freelocale(locale_); }
|
||||
|
||||
|
||||
@ -39,13 +39,13 @@ class printf_precision_handler {
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
int operator()(T value) {
|
||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
FMT_THROW(format_error("number is too big"));
|
||||
FMT_ERROR(Error_type::format_error, "number is too big");
|
||||
return (std::max)(static_cast<int>(value), 0);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
int operator()(T) {
|
||||
FMT_THROW(format_error("precision is not integer"));
|
||||
FMT_ERROR(Error_type::format_error, "precision is not integer");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@ -167,13 +167,13 @@ template <typename Char> class printf_width_handler {
|
||||
width = 0 - width;
|
||||
}
|
||||
unsigned int_max = max_value<int>();
|
||||
if (width > int_max) FMT_THROW(format_error("number is too big"));
|
||||
if (width > int_max) FMT_ERROR(Error_type::format_error, "number is too big");
|
||||
return static_cast<unsigned>(width);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
unsigned operator()(T) {
|
||||
FMT_THROW(format_error("width is not integer"));
|
||||
FMT_ERROR(Error_type::format_error, "width is not integer");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@ -577,7 +577,9 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
|
||||
}
|
||||
|
||||
// Parse type.
|
||||
if (it == end) FMT_THROW(format_error("invalid format string"));
|
||||
if (it == end)
|
||||
FMT_ERROR(Error_type::format_error, "invalid format string",
|
||||
basic_string_view<Char>(start, static_cast<std::size_t>(end - start)));
|
||||
specs.type = static_cast<char>(*it++);
|
||||
if (arg.is_integral()) {
|
||||
// Normalize type.
|
||||
|
||||
36
src/os.cc
36
src/os.cc
@ -75,8 +75,8 @@ FMT_BEGIN_NAMESPACE
|
||||
#ifdef _WIN32
|
||||
detail::utf16_to_utf8::utf16_to_utf8(wstring_view s) {
|
||||
if (int error_code = convert(s)) {
|
||||
FMT_THROW(windows_error(error_code,
|
||||
"cannot convert string from UTF-16 to UTF-8"));
|
||||
FMT_ERROR(Error_type::windows_error, error_code,
|
||||
"cannot convert string from UTF-16 to UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,14 +154,14 @@ buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
|
||||
FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())),
|
||||
nullptr);
|
||||
if (!file_)
|
||||
FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str()));
|
||||
FMT_ERROR(Error_type::system_error, errno, "cannot open file {}", filename.c_str());
|
||||
}
|
||||
|
||||
void buffered_file::close() {
|
||||
if (!file_) return;
|
||||
int result = FMT_SYSTEM(fclose(file_));
|
||||
file_ = nullptr;
|
||||
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
|
||||
if (result != 0) FMT_ERROR(Error_type::system_error, errno, "cannot close file");
|
||||
}
|
||||
|
||||
// A macro used to prevent expansion of fileno on broken versions of MinGW.
|
||||
@ -169,7 +169,7 @@ void buffered_file::close() {
|
||||
|
||||
int buffered_file::fileno() const {
|
||||
int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_));
|
||||
if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor"));
|
||||
if (fd == -1) FMT_ERROR(Error_type::system_error, errno, "cannot get file descriptor");
|
||||
return fd;
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ file::file(cstring_view path, int oflag) {
|
||||
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode)));
|
||||
# endif
|
||||
if (fd_ == -1)
|
||||
FMT_THROW(system_error(errno, "cannot open file {}", path.c_str()));
|
||||
FMT_ERROR(Error_type::system_error, errno, "cannot open file {}", path.c_str());
|
||||
}
|
||||
|
||||
file::~file() FMT_NOEXCEPT {
|
||||
@ -199,7 +199,7 @@ void file::close() {
|
||||
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
|
||||
int result = FMT_POSIX_CALL(close(fd_));
|
||||
fd_ = -1;
|
||||
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
|
||||
if (result != 0) FMT_ERROR(Error_type::system_error, errno, "cannot close file");
|
||||
}
|
||||
|
||||
long long file::size() const {
|
||||
@ -213,7 +213,7 @@ long long file::size() const {
|
||||
if (size_lower == INVALID_FILE_SIZE) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != NO_ERROR)
|
||||
FMT_THROW(windows_error(GetLastError(), "cannot get file size"));
|
||||
FMT_ERROR(Error_type::windows_error, GetLastError(), "cannot get file size");
|
||||
}
|
||||
unsigned long long long_size = size_upper;
|
||||
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
|
||||
@ -221,7 +221,7 @@ long long file::size() const {
|
||||
using Stat = struct stat;
|
||||
Stat file_stat = Stat();
|
||||
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
|
||||
FMT_THROW(system_error(errno, "cannot get file attributes"));
|
||||
FMT_ERROR(Error_type::system_error, errno, "cannot get file attributes");
|
||||
static_assert(sizeof(long long) >= sizeof(file_stat.st_size),
|
||||
"return type of file::size is not large enough");
|
||||
return file_stat.st_size;
|
||||
@ -231,14 +231,14 @@ long long file::size() const {
|
||||
std::size_t file::read(void* buffer, std::size_t count) {
|
||||
RWResult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
|
||||
if (result < 0) FMT_THROW(system_error(errno, "cannot read from file"));
|
||||
if (result < 0) FMT_ERROR(Error_type::system_error, errno, "cannot read from file");
|
||||
return detail::to_unsigned(result);
|
||||
}
|
||||
|
||||
std::size_t file::write(const void* buffer, std::size_t count) {
|
||||
RWResult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
|
||||
if (result < 0) FMT_THROW(system_error(errno, "cannot write to file"));
|
||||
if (result < 0) FMT_ERROR(Error_type::system_error, errno, "cannot write to file");
|
||||
return detail::to_unsigned(result);
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ file file::dup(int fd) {
|
||||
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
|
||||
int new_fd = FMT_POSIX_CALL(dup(fd));
|
||||
if (new_fd == -1)
|
||||
FMT_THROW(system_error(errno, "cannot duplicate file descriptor {}", fd));
|
||||
FMT_ERROR(Error_type::system_error, errno, "cannot duplicate file descriptor {}", fd);
|
||||
return file(new_fd);
|
||||
}
|
||||
|
||||
@ -255,8 +255,8 @@ void file::dup2(int fd) {
|
||||
int result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
|
||||
if (result == -1) {
|
||||
FMT_THROW(system_error(errno, "cannot duplicate file descriptor {} to {}",
|
||||
fd_, fd));
|
||||
FMT_ERROR(Error_type::system_error, errno, "cannot duplicate file descriptor {} to {}",
|
||||
fd_, fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +281,7 @@ void file::pipe(file& read_end, file& write_end) {
|
||||
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
|
||||
int result = FMT_POSIX_CALL(pipe(fds));
|
||||
# endif
|
||||
if (result != 0) FMT_THROW(system_error(errno, "cannot create pipe"));
|
||||
if (result != 0) FMT_ERROR(Error_type::system_error, errno, "cannot create pipe");
|
||||
// The following assignments don't throw because read_fd and write_fd
|
||||
// are closed.
|
||||
read_end = file(fds[0]);
|
||||
@ -296,8 +296,8 @@ buffered_file file::fdopen(const char* mode) {
|
||||
FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode));
|
||||
# endif
|
||||
if (!f)
|
||||
FMT_THROW(
|
||||
system_error(errno, "cannot associate stream with file descriptor"));
|
||||
FMT_ERROR(
|
||||
Error_type::system_error, errno, "cannot associate stream with file descriptor");
|
||||
buffered_file bf(f);
|
||||
fd_ = -1;
|
||||
return bf;
|
||||
@ -310,7 +310,7 @@ long getpagesize() {
|
||||
return si.dwPageSize;
|
||||
# else
|
||||
long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE));
|
||||
if (size < 0) FMT_THROW(system_error(errno, "cannot get memory page size"));
|
||||
if (size < 0) FMT_ERROR(Error_type::system_error, errno, "cannot get memory page size");
|
||||
return size;
|
||||
# endif
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user