mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-22 18:40:05 +00:00
Move safe_strerror to anonymous namespace.
This commit is contained in:
parent
b33d2aa825
commit
f2c9df8e9f
65
format.cc
65
format.cc
@ -138,6 +138,43 @@ const char RESET_COLOR[] = "\x1b[0m";
|
|||||||
|
|
||||||
typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
|
typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
|
||||||
|
|
||||||
|
// Portable thread-safe version of strerror.
|
||||||
|
// Sets buffer to point 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.
|
||||||
|
// Returns 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.
|
||||||
|
int safe_strerror(
|
||||||
|
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true) {
|
||||||
|
assert(buffer != 0 && buffer_size != 0);
|
||||||
|
int result = 0;
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
char *message = strerror_r(error_code, buffer, buffer_size);
|
||||||
|
// If the buffer is full then the message is probably truncated.
|
||||||
|
if (message == buffer && strlen(buffer) == buffer_size - 1)
|
||||||
|
result = ERANGE;
|
||||||
|
buffer = message;
|
||||||
|
#elif __MINGW32__
|
||||||
|
errno = 0;
|
||||||
|
(void)buffer_size;
|
||||||
|
buffer = strerror(error_code);
|
||||||
|
result = errno;
|
||||||
|
#elif _WIN32
|
||||||
|
result = strerror_s(buffer, buffer_size, error_code);
|
||||||
|
// If the buffer is full then the message is probably truncated.
|
||||||
|
if (result == 0 && std::strlen(buffer) == buffer_size - 1)
|
||||||
|
result = ERANGE;
|
||||||
|
#else
|
||||||
|
result = strerror_r(error_code, buffer, buffer_size);
|
||||||
|
if (result == -1)
|
||||||
|
result = errno; // glibc versions before 2.13 return result in errno.
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void format_error_code(fmt::Writer &out, int error_code,
|
void format_error_code(fmt::Writer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT(true) {
|
fmt::StringRef message) FMT_NOEXCEPT(true) {
|
||||||
// Report error code making sure that the output fits into
|
// Report error code making sure that the output fits into
|
||||||
@ -442,34 +479,6 @@ void fmt::WindowsError::init(
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int fmt::internal::safe_strerror(
|
|
||||||
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true) {
|
|
||||||
assert(buffer != 0 && buffer_size != 0);
|
|
||||||
int result = 0;
|
|
||||||
#ifdef _GNU_SOURCE
|
|
||||||
char *message = strerror_r(error_code, buffer, buffer_size);
|
|
||||||
// If the buffer is full then the message is probably truncated.
|
|
||||||
if (message == buffer && strlen(buffer) == buffer_size - 1)
|
|
||||||
result = ERANGE;
|
|
||||||
buffer = message;
|
|
||||||
#elif __MINGW32__
|
|
||||||
errno = 0;
|
|
||||||
(void)buffer_size;
|
|
||||||
buffer = strerror(error_code);
|
|
||||||
result = errno;
|
|
||||||
#elif _WIN32
|
|
||||||
result = strerror_s(buffer, buffer_size, error_code);
|
|
||||||
// If the buffer is full then the message is probably truncated.
|
|
||||||
if (result == 0 && std::strlen(buffer) == buffer_size - 1)
|
|
||||||
result = ERANGE;
|
|
||||||
#else
|
|
||||||
result = strerror_r(error_code, buffer, buffer_size);
|
|
||||||
if (result == -1)
|
|
||||||
result = errno; // glibc versions before 2.13 return result in errno.
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fmt::internal::format_system_error(
|
void fmt::internal::format_system_error(
|
||||||
fmt::Writer &out, int error_code,
|
fmt::Writer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT(true) {
|
fmt::StringRef message) FMT_NOEXCEPT(true) {
|
||||||
|
12
format.h
12
format.h
@ -534,18 +534,6 @@ class UTF16ToUTF8 {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Portable thread-safe version of strerror.
|
|
||||||
// Sets buffer to point 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.
|
|
||||||
// Returns 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.
|
|
||||||
int safe_strerror(int error_code,
|
|
||||||
char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true);
|
|
||||||
|
|
||||||
void format_system_error(fmt::Writer &out, int error_code,
|
void format_system_error(fmt::Writer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT(true);
|
fmt::StringRef message) FMT_NOEXCEPT(true);
|
||||||
|
|
||||||
|
@ -27,7 +27,11 @@
|
|||||||
|
|
||||||
// Include format.cc instead of format.h to test implementation-specific stuff.
|
// Include format.cc instead of format.h to test implementation-specific stuff.
|
||||||
#include "format.cc"
|
#include "format.cc"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "gtest-extra.h"
|
#include "gtest-extra.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#undef max
|
#undef max
|
||||||
|
|
||||||
@ -48,6 +52,39 @@ TEST(FormatTest, FormatNegativeNaN) {
|
|||||||
fmt::print("Warning: compiler doesn't handle negative NaN correctly");
|
fmt::print("Warning: compiler doesn't handle negative NaN correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatTest, StrError) {
|
||||||
|
char *message = 0;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
#ifndef NDEBUG
|
||||||
|
EXPECT_DEBUG_DEATH(safe_strerror(EDOM, message = 0, 0), "Assertion");
|
||||||
|
EXPECT_DEBUG_DEATH(safe_strerror(EDOM, message = buffer, 0), "Assertion");
|
||||||
|
#endif
|
||||||
|
buffer[0] = 'x';
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
// Use invalid error code to make sure that safe_strerror returns an error
|
||||||
|
// message in the buffer rather than a pointer to a static string.
|
||||||
|
int error_code = -1;
|
||||||
|
#else
|
||||||
|
int error_code = EDOM;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int result = safe_strerror(error_code, message = buffer, BUFFER_SIZE);
|
||||||
|
EXPECT_EQ(0, result);
|
||||||
|
std::size_t message_size = std::strlen(message);
|
||||||
|
EXPECT_GE(BUFFER_SIZE - 1u, message_size);
|
||||||
|
EXPECT_EQ(get_system_error(error_code), message);
|
||||||
|
|
||||||
|
// safe_strerror never uses buffer on MinGW.
|
||||||
|
#ifndef __MINGW32__
|
||||||
|
result = safe_strerror(error_code, message = buffer, message_size);
|
||||||
|
EXPECT_EQ(ERANGE, result);
|
||||||
|
result = safe_strerror(error_code, message = buffer, 1);
|
||||||
|
EXPECT_EQ(buffer, message); // Message should point to buffer.
|
||||||
|
EXPECT_EQ(ERANGE, result);
|
||||||
|
EXPECT_STREQ("", message);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FormatTest, FormatErrorCode) {
|
TEST(FormatTest, FormatErrorCode) {
|
||||||
std::string msg = "error 42", sep = ": ";
|
std::string msg = "error 42", sep = ": ";
|
||||||
{
|
{
|
||||||
|
@ -46,18 +46,6 @@ using fmt::internal::Arg;
|
|||||||
using fmt::internal::MakeArg;
|
using fmt::internal::MakeArg;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::string get_system_error(int error_code) {
|
|
||||||
#if defined(__MINGW32__) || !defined(_WIN32)
|
|
||||||
return strerror(error_code);
|
|
||||||
#else
|
|
||||||
enum { BUFFER_SIZE = 200 };
|
|
||||||
char buffer[BUFFER_SIZE];
|
|
||||||
EXPECT_EQ(0, strerror_s(buffer, BUFFER_SIZE, error_code));
|
|
||||||
std::size_t max_len = BUFFER_SIZE - 1;
|
|
||||||
EXPECT_LT(std::strlen(buffer), max_len);
|
|
||||||
return buffer;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Test {};
|
struct Test {};
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@ -417,40 +405,6 @@ TEST(UtilTest, UTF16ToUTF8Convert) {
|
|||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
TEST(UtilTest, StrError) {
|
|
||||||
using fmt::internal::safe_strerror;
|
|
||||||
char *message = 0;
|
|
||||||
char buffer[BUFFER_SIZE];
|
|
||||||
#ifndef NDEBUG
|
|
||||||
EXPECT_DEBUG_DEATH(safe_strerror(EDOM, message = 0, 0), "Assertion");
|
|
||||||
EXPECT_DEBUG_DEATH(safe_strerror(EDOM, message = buffer, 0), "Assertion");
|
|
||||||
#endif
|
|
||||||
buffer[0] = 'x';
|
|
||||||
#ifdef _GNU_SOURCE
|
|
||||||
// Use invalid error code to make sure that safe_strerror returns an error
|
|
||||||
// message in the buffer rather than a pointer to a static string.
|
|
||||||
int error_code = -1;
|
|
||||||
#else
|
|
||||||
int error_code = EDOM;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int result = safe_strerror(error_code, message = buffer, BUFFER_SIZE);
|
|
||||||
EXPECT_EQ(0, result);
|
|
||||||
std::size_t message_size = std::strlen(message);
|
|
||||||
EXPECT_GE(BUFFER_SIZE - 1u, message_size);
|
|
||||||
EXPECT_EQ(get_system_error(error_code), message);
|
|
||||||
|
|
||||||
// safe_strerror never uses buffer on MinGW.
|
|
||||||
#ifndef __MINGW32__
|
|
||||||
result = safe_strerror(error_code, message = buffer, message_size);
|
|
||||||
EXPECT_EQ(ERANGE, result);
|
|
||||||
result = safe_strerror(error_code, message = buffer, 1);
|
|
||||||
EXPECT_EQ(buffer, message); // Message should point to buffer.
|
|
||||||
EXPECT_EQ(ERANGE, result);
|
|
||||||
EXPECT_STREQ("", message);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef void (*FormatErrorMessage)(
|
typedef void (*FormatErrorMessage)(
|
||||||
fmt::Writer &out, int error_code, StringRef message);
|
fmt::Writer &out, int error_code, StringRef message);
|
||||||
|
|
||||||
|
13
test/util.cc
13
test/util.cc
@ -37,3 +37,16 @@ void increment(char *s) {
|
|||||||
s[i] = '0';
|
s[i] = '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string get_system_error(int error_code) {
|
||||||
|
#if defined(__MINGW32__) || !defined(_WIN32)
|
||||||
|
return strerror(error_code);
|
||||||
|
#else
|
||||||
|
enum { BUFFER_SIZE = 200 };
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
EXPECT_EQ(0, strerror_s(buffer, BUFFER_SIZE, error_code));
|
||||||
|
std::size_t max_len = BUFFER_SIZE - 1;
|
||||||
|
EXPECT_LT(std::strlen(buffer), max_len);
|
||||||
|
return buffer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
enum {BUFFER_SIZE = 256};
|
enum {BUFFER_SIZE = 256};
|
||||||
|
|
||||||
@ -46,3 +47,5 @@ void safe_sprintf(char (&buffer)[SIZE], const char *format, ...) {
|
|||||||
|
|
||||||
// Increment a number in a string.
|
// Increment a number in a string.
|
||||||
void increment(char *s);
|
void increment(char *s);
|
||||||
|
|
||||||
|
std::string get_system_error(int error_code);
|
||||||
|
Loading…
Reference in New Issue
Block a user