mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Add a portable thread-safe version of strerror.
This commit is contained in:
@ -248,6 +248,22 @@ TEST(UtilTest, UTF8ToUTF16) {
|
|||||||
// TODO: test UTF16ToUTF8::Convert
|
// TODO: test UTF16ToUTF8::Convert
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
TEST(UtilTest, StrError) {
|
||||||
|
using fmt::internal::StrError;
|
||||||
|
EXPECT_DEBUG_DEATH(StrError(EDOM, 0, 0), "Assertion");
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
EXPECT_DEBUG_DEATH(StrError(EDOM, buffer, 0), "Assertion");
|
||||||
|
buffer[0] = 'x';
|
||||||
|
const char *message = StrError(-1, buffer, 1);
|
||||||
|
EXPECT_EQ(ERANGE, errno);
|
||||||
|
EXPECT_STREQ("", message);
|
||||||
|
message = StrError(-1, buffer, BUFFER_SIZE);
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_GE(BUFFER_SIZE - 1, std::strlen(message));
|
||||||
|
message = StrError(-1, buffer, std::strlen(message));
|
||||||
|
EXPECT_EQ(ERANGE, errno);
|
||||||
|
}
|
||||||
|
|
||||||
class TestString {
|
class TestString {
|
||||||
private:
|
private:
|
||||||
std::string value_;
|
std::string value_;
|
||||||
|
20
format.cc
20
format.cc
@ -204,6 +204,26 @@ int fmt::internal::UTF16ToUTF8::Convert(fmt::WStringRef s) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char *fmt::internal::StrError(
|
||||||
|
int error_code, char *buffer, std::size_t buffer_size) {
|
||||||
|
assert(buffer != 0 && buffer_size != 0);
|
||||||
|
errno = 0;
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
char *message = strerror_r(error_code, buffer, buffer_size);
|
||||||
|
if (message == buffer && strlen(buffer) == buffer_size - 1)
|
||||||
|
errno = ERANGE; // The buffer is full so the message is probably truncated.
|
||||||
|
return message;
|
||||||
|
#elif _WIN32
|
||||||
|
errno = strerror_s(buffer, buflen, error_code);
|
||||||
|
if (errno == 0 && std::strlen(buffer) == buffer_size - 1)
|
||||||
|
errno = ERANGE; // The buffer is full so the message is probably truncated.
|
||||||
|
return buffer;
|
||||||
|
#else
|
||||||
|
strerror_r(error_code, buffer, buffer_size);
|
||||||
|
return buffer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void fmt::internal::FormatSystemErrorMessage(
|
void fmt::internal::FormatSystemErrorMessage(
|
||||||
fmt::Writer &out, int error_code, fmt::StringRef message) {
|
fmt::Writer &out, int error_code, fmt::StringRef message) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
11
format.h
11
format.h
@ -489,6 +489,16 @@ class UTF16ToUTF8 {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Portable thread-safe version of strerror.
|
||||||
|
// Returns a pointer to a string describing the error code. This can be
|
||||||
|
// either a pointer to a string stored in buffer, or a pointer to some
|
||||||
|
// static immutable string. Sets errno to one of the following values:
|
||||||
|
// 0 - success
|
||||||
|
// ERANGE - buffer is not large enough to store the error message
|
||||||
|
// other - failure
|
||||||
|
// Buffer should be at least of size 1.
|
||||||
|
char *StrError(int error_code, char *buffer, std::size_t buffer_size);
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
@ -1521,7 +1531,6 @@ inline Formatter<NullSink, wchar_t> Format(WStringRef format) {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A sink that gets the system error message corresponding to the error code
|
A sink that gets the system error message corresponding to the error code
|
||||||
and throws SystemError.
|
and throws SystemError.
|
||||||
|
Reference in New Issue
Block a user