Add ThrowCError to throw an exception on C library errors.
This commit is contained in:
parent
2c6372d790
commit
f79398699b
@ -260,6 +260,7 @@ TEST(UtilTest, StrError) {
|
|||||||
message = StrError(-1, buffer, BUFFER_SIZE);
|
message = StrError(-1, buffer, BUFFER_SIZE);
|
||||||
EXPECT_EQ(0, errno);
|
EXPECT_EQ(0, errno);
|
||||||
EXPECT_GE(BUFFER_SIZE - 1, std::strlen(message));
|
EXPECT_GE(BUFFER_SIZE - 1, std::strlen(message));
|
||||||
|
EXPECT_STREQ(strerror(-1), message);
|
||||||
message = StrError(-1, buffer, std::strlen(message));
|
message = StrError(-1, buffer, std::strlen(message));
|
||||||
EXPECT_EQ(ERANGE, errno);
|
EXPECT_EQ(ERANGE, errno);
|
||||||
}
|
}
|
||||||
|
22
format.cc
22
format.cc
@ -224,19 +224,13 @@ char *fmt::internal::StrError(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void fmt::internal::FormatSystemErrorMessage(
|
void fmt::internal::FormatCErrorMessage(
|
||||||
fmt::Writer &out, int error_code, fmt::StringRef message) {
|
fmt::Writer &out, int error_code, fmt::StringRef message) {
|
||||||
#ifndef _WIN32
|
|
||||||
Array<char, INLINE_BUFFER_SIZE> buffer;
|
Array<char, INLINE_BUFFER_SIZE> buffer;
|
||||||
buffer.resize(INLINE_BUFFER_SIZE);
|
buffer.resize(INLINE_BUFFER_SIZE);
|
||||||
char *system_message = 0;
|
char *system_message = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
errno = 0;
|
system_message = StrError(error_code, &buffer[0], buffer.size());
|
||||||
# ifdef _GNU_SOURCE
|
|
||||||
system_message = strerror_r(error_code, &buffer[0], buffer.size());
|
|
||||||
# else
|
|
||||||
strerror_r(error_code, system_message = &buffer[0], buffer.size());
|
|
||||||
# endif
|
|
||||||
if (errno == 0)
|
if (errno == 0)
|
||||||
break;
|
break;
|
||||||
if (errno != ERANGE) {
|
if (errno != ERANGE) {
|
||||||
@ -247,6 +241,12 @@ void fmt::internal::FormatSystemErrorMessage(
|
|||||||
buffer.resize(buffer.size() * 2);
|
buffer.resize(buffer.size() * 2);
|
||||||
}
|
}
|
||||||
out << message << ": " << system_message;
|
out << message << ": " << system_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fmt::internal::FormatSystemErrorMessage(
|
||||||
|
fmt::Writer &out, int error_code, fmt::StringRef message) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
FormatCErrorMessage(out, error_code, message);
|
||||||
#else
|
#else
|
||||||
class String {
|
class String {
|
||||||
private:
|
private:
|
||||||
@ -806,6 +806,12 @@ void fmt::SystemErrorSink::operator()(const fmt::Writer &w) const {
|
|||||||
throw SystemError(message.c_str(), error_code_);
|
throw SystemError(message.c_str(), error_code_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fmt::CErrorSink::operator()(const Writer &w) const {
|
||||||
|
Writer message;
|
||||||
|
internal::FormatCErrorMessage(message, error_code_, w.c_str());
|
||||||
|
throw SystemError(message.c_str(), error_code_);
|
||||||
|
}
|
||||||
|
|
||||||
void fmt::ANSITerminalSink::operator()(
|
void fmt::ANSITerminalSink::operator()(
|
||||||
const fmt::BasicWriter<char> &w) const {
|
const fmt::BasicWriter<char> &w) const {
|
||||||
char escape[] = "\x1b[30m";
|
char escape[] = "\x1b[30m";
|
||||||
|
45
format.h
45
format.h
@ -499,6 +499,9 @@ class UTF16ToUTF8 {
|
|||||||
// Buffer should be at least of size 1.
|
// Buffer should be at least of size 1.
|
||||||
char *StrError(int error_code, char *buffer, std::size_t buffer_size);
|
char *StrError(int error_code, char *buffer, std::size_t buffer_size);
|
||||||
|
|
||||||
|
// Formats a standard C library error message writing the output to out.
|
||||||
|
void FormatCErrorMessage(Writer &out, int error_code, StringRef message);
|
||||||
|
|
||||||
// Formats a system error message writing the output to out.
|
// Formats a system error message writing the output to out.
|
||||||
void FormatSystemErrorMessage(Writer &out, int error_code, StringRef message);
|
void FormatSystemErrorMessage(Writer &out, int error_code, StringRef message);
|
||||||
|
|
||||||
@ -1520,7 +1523,7 @@ class Formatter : private Sink, public BasicFormatter<Char> {
|
|||||||
|
|
||||||
See also `Format String Syntax`_.
|
See also `Format String Syntax`_.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
inline Formatter<> Format(StringRef format) {
|
inline Formatter<> Format(StringRef format) {
|
||||||
Formatter<> f(format);
|
Formatter<> f(format);
|
||||||
return f;
|
return f;
|
||||||
@ -1532,7 +1535,7 @@ inline Formatter<NullSink, wchar_t> Format(WStringRef format) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A sink that gets the system error message corresponding to the error code
|
A sink that gets the error message corresponding to a system error code
|
||||||
and throws SystemError.
|
and throws SystemError.
|
||||||
*/
|
*/
|
||||||
class SystemErrorSink {
|
class SystemErrorSink {
|
||||||
@ -1545,13 +1548,45 @@ class SystemErrorSink {
|
|||||||
void operator()(const Writer &w) const;
|
void operator()(const Writer &w) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Throws SystemError with a code and a formatted message. */
|
/**
|
||||||
|
Formats a message and throws SystemError with the description of the form
|
||||||
|
"<message>: <system-message>", where <message> is the formatted message and
|
||||||
|
<system-message> is the system message corresponding to the error code.
|
||||||
|
error_code is a system error code as given by errno for POSIX and
|
||||||
|
GetLastError for Windows.
|
||||||
|
*/
|
||||||
inline Formatter<SystemErrorSink> ThrowSystemError(
|
inline Formatter<SystemErrorSink> ThrowSystemError(
|
||||||
int error_code, StringRef format = 0) {
|
int error_code, StringRef format) {
|
||||||
Formatter<SystemErrorSink> f(format, SystemErrorSink(error_code));
|
Formatter<SystemErrorSink> f(format, SystemErrorSink(error_code));
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
A sink that gets the error message corresponding to a standard C library
|
||||||
|
error code as given by errno and throws SystemError.
|
||||||
|
*/
|
||||||
|
class CErrorSink {
|
||||||
|
private:
|
||||||
|
int error_code_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CErrorSink(int error_code) : error_code_(error_code) {}
|
||||||
|
|
||||||
|
void operator()(const Writer &w) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Formats a message and throws SystemError with the description of the form
|
||||||
|
"<message>: <system-message>", where <message> is the formatted message and
|
||||||
|
<system-message> is the system message corresponding to the error code.
|
||||||
|
error_code is an error code as given by errno after calling a C library
|
||||||
|
function.
|
||||||
|
*/
|
||||||
|
inline Formatter<CErrorSink> ThrowCError(int error_code, StringRef format) {
|
||||||
|
Formatter<CErrorSink> f(format, CErrorSink(error_code));
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
/** A sink that writes output to a file. */
|
/** A sink that writes output to a file. */
|
||||||
class FileSink {
|
class FileSink {
|
||||||
private:
|
private:
|
||||||
@ -1563,7 +1598,7 @@ class FileSink {
|
|||||||
/** Writes the output to a file. */
|
/** Writes the output to a file. */
|
||||||
void operator()(const BasicWriter<char> &w) const {
|
void operator()(const BasicWriter<char> &w) const {
|
||||||
if (std::fwrite(w.data(), w.size(), 1, file_) == 0)
|
if (std::fwrite(w.data(), w.size(), 1, file_) == 0)
|
||||||
ThrowSystemError(errno, "cannot write to file");
|
ThrowCError(errno, "cannot write to file");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user