Merge 2fb9ddafc6 into 950e6b9753
This commit is contained in:
commit
f5e8144cc5
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,3 +15,4 @@ CTestTestfile.cmake
|
|||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
Makefile
|
Makefile
|
||||||
|
/run-msbuild.bat
|
||||||
|
|||||||
@ -25,6 +25,12 @@ include(CheckCXXCompilerFlag)
|
|||||||
check_cxx_compiler_flag(-std=c++11 HAVE_STD_CPP11_FLAG)
|
check_cxx_compiler_flag(-std=c++11 HAVE_STD_CPP11_FLAG)
|
||||||
if (HAVE_STD_CPP11_FLAG)
|
if (HAVE_STD_CPP11_FLAG)
|
||||||
set(CPP11_FLAG -std=c++11)
|
set(CPP11_FLAG -std=c++11)
|
||||||
|
# Use libc++.
|
||||||
|
# We may link with libc++abi as well, leave it for now
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
message(STATUS "${CMAKE_CXX_COMPILER_ID} detected! Use libc++ as its standard library.")
|
||||||
|
set(CPP11_FLAG "-std=c++11 -stdlib=libc++ -lc++")
|
||||||
|
endif ()
|
||||||
else ()
|
else ()
|
||||||
check_cxx_compiler_flag(-std=c++0x HAVE_STD_CPP0X_FLAG)
|
check_cxx_compiler_flag(-std=c++0x HAVE_STD_CPP0X_FLAG)
|
||||||
if (HAVE_STD_CPP0X_FLAG)
|
if (HAVE_STD_CPP0X_FLAG)
|
||||||
@ -74,12 +80,15 @@ if (BIICODE)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_library(format ${FMT_SOURCES})
|
add_library(format ${FMT_SOURCES})
|
||||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
set_target_properties(format PROPERTIES COMPILE_FLAGS
|
set_target_properties(format PROPERTIES COMPILE_FLAGS
|
||||||
"-Wall -Wextra -Wshadow -pedantic")
|
"-Wall -Wextra -Wshadow -pedantic")
|
||||||
|
if (CPP11_FLAG)
|
||||||
|
set_target_properties(format PROPERTIES COMPILE_FLAGS
|
||||||
|
"-Wall -Wextra -Wshadow -pedantic ${CPP11_FLAG}")
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
if (CPP11_FLAG AND FMT_EXTRA_TESTS)
|
if (CPP11_FLAG AND FMT_EXTRA_TESTS)
|
||||||
set_target_properties(format PROPERTIES COMPILE_FLAGS ${CPP11_FLAG})
|
|
||||||
# Test compilation with default flags.
|
# Test compilation with default flags.
|
||||||
file(GLOB src RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} test/*.cc test/*.h)
|
file(GLOB src RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} test/*.cc test/*.h)
|
||||||
add_library(testformat STATIC ${FMT_SOURCE_FILES} ${src})
|
add_library(testformat STATIC ${FMT_SOURCE_FILES} ${src})
|
||||||
@ -108,6 +117,41 @@ if (NOT FMT_VARIADIC_TEMPLATES)
|
|||||||
add_definitions(-DGTEST_LANG_CXX11=0)
|
add_definitions(-DGTEST_LANG_CXX11=0)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
struct C{
|
||||||
|
C()=delete;
|
||||||
|
C(const C&)=delete;
|
||||||
|
C& operator=(const C&)=delete;
|
||||||
|
};
|
||||||
|
int main(){}" FMT_DELETED_FUNCTIONS)
|
||||||
|
if (FMT_DELETED_FUNCTIONS)
|
||||||
|
# add_definitions(-DFMT_USE_DELETED_FUNCTIONS=1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
void f() noexcept {}
|
||||||
|
int main(){ f(); }" FMT_BASIC_NOEXCEPT_SUPPORT)
|
||||||
|
if (FMT_BASIC_NOEXCEPT_SUPPORT)
|
||||||
|
# add_definitions(-DFMT_USE_NOEXCEPT=1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <utility>
|
||||||
|
struct MoveOnly {
|
||||||
|
MoveOnly() {}
|
||||||
|
MoveOnly(MoveOnly&&) {}
|
||||||
|
private:
|
||||||
|
MoveOnly(const MoveOnly&);
|
||||||
|
};
|
||||||
|
int main() {
|
||||||
|
MoveOnly a;
|
||||||
|
MoveOnly b(std::move(a));
|
||||||
|
MoveOnly c(MoveOnly());
|
||||||
|
}" FMT_RVALUE_REFERENCES)
|
||||||
|
if (FMT_RVALUE_REFERENCES)
|
||||||
|
# add_definitions(-DFMT_USE_RVALUE_REFERENCES=1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
# GTest doesn't detect <tuple> with clang.
|
# GTest doesn't detect <tuple> with clang.
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
target_compile_definitions(gmock PUBLIC GTEST_USE_OWN_TR1_TUPLE=1)
|
target_compile_definitions(gmock PUBLIC GTEST_USE_OWN_TR1_TUPLE=1)
|
||||||
|
|||||||
16
format.cc
16
format.cc
@ -146,7 +146,7 @@ typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
|
|||||||
// other - failure
|
// other - failure
|
||||||
// Buffer should be at least of size 1.
|
// Buffer should be at least of size 1.
|
||||||
int safe_strerror(
|
int safe_strerror(
|
||||||
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true) {
|
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
|
||||||
assert(buffer != 0 && buffer_size != 0);
|
assert(buffer != 0 && buffer_size != 0);
|
||||||
int result = 0;
|
int result = 0;
|
||||||
#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || __ANDROID__
|
#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || __ANDROID__
|
||||||
@ -180,7 +180,7 @@ int safe_strerror(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
// Report error code making sure that the output fits into
|
// Report error code making sure that the output fits into
|
||||||
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
|
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
|
||||||
// bad_alloc.
|
// bad_alloc.
|
||||||
@ -198,7 +198,7 @@ void format_error_code(fmt::Writer &out, int error_code,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void report_error(FormatFunc func,
|
void report_error(FormatFunc func,
|
||||||
int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) {
|
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
|
||||||
fmt::MemoryWriter full_message;
|
fmt::MemoryWriter full_message;
|
||||||
func(full_message, error_code, message);
|
func(full_message, error_code, message);
|
||||||
// Use Writer::data instead of Writer::c_str to avoid potential memory
|
// Use Writer::data instead of Writer::c_str to avoid potential memory
|
||||||
@ -500,7 +500,7 @@ FMT_FUNC void fmt::WindowsError::init(
|
|||||||
|
|
||||||
FMT_FUNC void fmt::internal::format_system_error(
|
FMT_FUNC 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 {
|
||||||
FMT_TRY {
|
FMT_TRY {
|
||||||
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
|
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
|
||||||
buffer.resize(INLINE_BUFFER_SIZE);
|
buffer.resize(INLINE_BUFFER_SIZE);
|
||||||
@ -522,7 +522,7 @@ FMT_FUNC void fmt::internal::format_system_error(
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
FMT_FUNC void fmt::internal::format_windows_error(
|
FMT_FUNC void fmt::internal::format_windows_error(
|
||||||
fmt::Writer &out, int error_code,
|
fmt::Writer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT(true) {
|
fmt::StringRef message) FMT_NOEXCEPT {
|
||||||
class String {
|
class String {
|
||||||
private:
|
private:
|
||||||
LPWSTR str_;
|
LPWSTR str_;
|
||||||
@ -1083,13 +1083,13 @@ void fmt::BasicFormatter<Char>::format(
|
|||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC void fmt::report_system_error(
|
FMT_FUNC void fmt::report_system_error(
|
||||||
int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) {
|
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
|
||||||
report_error(internal::format_system_error, error_code, message);
|
report_error(internal::format_system_error, error_code, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
FMT_FUNC void fmt::report_windows_error(
|
FMT_FUNC void fmt::report_windows_error(
|
||||||
int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) {
|
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
|
||||||
report_error(internal::format_windows_error, error_code, message);
|
report_error(internal::format_windows_error, error_code, message);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1119,7 +1119,7 @@ FMT_FUNC void fmt::print_colored(Color c, StringRef format, ArgList args) {
|
|||||||
if (!GetConsoleScreenBufferInfo(handle, &info_con))
|
if (!GetConsoleScreenBufferInfo(handle, &info_con))
|
||||||
FMT_THROW(WindowsError(GetLastError(), "cannot get console information"));
|
FMT_THROW(WindowsError(GetLastError(), "cannot get console information"));
|
||||||
WORD reset_color = info_con.wAttributes;
|
WORD reset_color = info_con.wAttributes;
|
||||||
WORD color = static_cast<int>(c) >= ARRAYSIZE(WIN32_COLORS) ? reset_color : WIN32_COLORS[c];
|
WORD color = static_cast<size_t>(c) >= ARRAYSIZE(WIN32_COLORS) ? reset_color : WIN32_COLORS[c];
|
||||||
if (!SetConsoleTextAttribute(handle, color))
|
if (!SetConsoleTextAttribute(handle, color))
|
||||||
FMT_THROW(WindowsError(GetLastError(), "cannot set console color"));
|
FMT_THROW(WindowsError(GetLastError(), "cannot set console color"));
|
||||||
print(format, args);
|
print(format, args);
|
||||||
|
|||||||
36
format.h
36
format.h
@ -92,7 +92,7 @@
|
|||||||
// since version 2013.
|
// since version 2013.
|
||||||
# define FMT_USE_VARIADIC_TEMPLATES \
|
# define FMT_USE_VARIADIC_TEMPLATES \
|
||||||
(FMT_HAS_FEATURE(cxx_variadic_templates) || \
|
(FMT_HAS_FEATURE(cxx_variadic_templates) || \
|
||||||
(FMT_GCC_VERSION >= 404 && __cplusplus >= 201103) || _MSC_VER >= 1800)
|
(FMT_GCC_VERSION >= 404 && __cplusplus >= 201103L) || _MSC_VER >= 1800)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_USE_RVALUE_REFERENCES
|
#ifndef FMT_USE_RVALUE_REFERENCES
|
||||||
@ -103,7 +103,7 @@
|
|||||||
# else
|
# else
|
||||||
# define FMT_USE_RVALUE_REFERENCES \
|
# define FMT_USE_RVALUE_REFERENCES \
|
||||||
(FMT_HAS_FEATURE(cxx_rvalue_references) || \
|
(FMT_HAS_FEATURE(cxx_rvalue_references) || \
|
||||||
(FMT_GCC_VERSION >= 403 && __cplusplus >= 201103) || _MSC_VER >= 1600)
|
(FMT_GCC_VERSION >= 403 && __cplusplus >= 201103L) || _MSC_VER >= 1600)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -113,17 +113,25 @@
|
|||||||
|
|
||||||
// Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature).
|
// Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature).
|
||||||
#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
|
#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
|
||||||
(FMT_GCC_VERSION >= 408 && __cplusplus >= 201103)
|
(FMT_GCC_VERSION >= 408 && __cplusplus >= 201103L)
|
||||||
# define FMT_NOEXCEPT(expr) noexcept(expr)
|
# define FMT_NOEXCEPT noexcept
|
||||||
#else
|
#else
|
||||||
# define FMT_NOEXCEPT(expr)
|
# define FMT_NOEXCEPT throw()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// A macro to disallow the copy constructor and operator= functions
|
// A macro to disallow the copy constructor and operator= functions
|
||||||
// This should be used in the private: declarations for a class
|
// This should be used in the private: declarations for a class
|
||||||
|
#if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions)\
|
||||||
|
|| (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103L)\
|
||||||
|
|| (_MSC_VER >= 1800)
|
||||||
|
#define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||||
|
TypeName(const TypeName&) = delete; \
|
||||||
|
TypeName& operator=(const TypeName&) = delete
|
||||||
|
#else
|
||||||
#define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
#define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||||
TypeName(const TypeName&); \
|
TypeName(const TypeName&); \
|
||||||
void operator=(const TypeName&)
|
TypeName& operator=(const TypeName&)
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace fmt {
|
namespace fmt {
|
||||||
|
|
||||||
@ -290,7 +298,7 @@ class Buffer {
|
|||||||
grow(capacity);
|
grow(capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() FMT_NOEXCEPT(true) { size_ = 0; }
|
void clear() FMT_NOEXCEPT { size_ = 0; }
|
||||||
|
|
||||||
void push_back(const T &value) {
|
void push_back(const T &value) {
|
||||||
if (size_ == capacity_)
|
if (size_ == capacity_)
|
||||||
@ -623,11 +631,11 @@ class UTF16ToUTF8 {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void format_windows_error(fmt::Writer &out, int error_code,
|
void format_windows_error(fmt::Writer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT(true);
|
fmt::StringRef message) FMT_NOEXCEPT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Computes max(Arg, 1) at compile time. It is used to avoid errors about
|
// Computes max(Arg, 1) at compile time. It is used to avoid errors about
|
||||||
@ -1561,7 +1569,7 @@ class BasicWriter {
|
|||||||
Returns a pointer to the output buffer content. No terminating null
|
Returns a pointer to the output buffer content. No terminating null
|
||||||
character is appended.
|
character is appended.
|
||||||
*/
|
*/
|
||||||
const Char *data() const FMT_NOEXCEPT(true) { return &buffer_[0]; }
|
const Char *data() const FMT_NOEXCEPT { return &buffer_[0]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a pointer to the output buffer content with terminating null
|
Returns a pointer to the output buffer content with terminating null
|
||||||
@ -1685,7 +1693,7 @@ class BasicWriter {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() FMT_NOEXCEPT(true) { buffer_.clear(); }
|
void clear() FMT_NOEXCEPT { buffer_.clear(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@ -2102,7 +2110,7 @@ void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {
|
|||||||
|
|
||||||
// Reports a system error without throwing an exception.
|
// Reports a system error without throwing an exception.
|
||||||
// Can be used to report errors from destructors.
|
// Can be used to report errors from destructors.
|
||||||
void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT(true);
|
void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
@ -2146,7 +2154,7 @@ class WindowsError : public SystemError {
|
|||||||
|
|
||||||
// Reports a Windows error without throwing an exception.
|
// Reports a Windows error without throwing an exception.
|
||||||
// Can be used to report errors from destructors.
|
// Can be used to report errors from destructors.
|
||||||
void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT(true);
|
void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2489,6 +2497,8 @@ FMT_VARIADIC(int, fprintf, std::FILE *, StringRef)
|
|||||||
|
|
||||||
#ifdef FMT_HEADER_ONLY
|
#ifdef FMT_HEADER_ONLY
|
||||||
# include "format.cc"
|
# include "format.cc"
|
||||||
|
#elif _MSC_VER
|
||||||
|
# pragma comment(lib, "format.lib")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // FMT_FORMAT_H_
|
#endif // FMT_FORMAT_H_
|
||||||
|
|||||||
48
posix.cc
48
posix.cc
@ -75,7 +75,9 @@ inline std::size_t convert_rwcount(std::size_t count) { return count; }
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT(true) {
|
// Implementations of fmt::BufferedFile
|
||||||
|
|
||||||
|
fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT {
|
||||||
if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
|
if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
|
||||||
fmt::report_system_error(errno, "cannot close file");
|
fmt::report_system_error(errno, "cannot close file");
|
||||||
}
|
}
|
||||||
@ -102,6 +104,35 @@ int fmt::BufferedFile::fileno() const {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fmt::BufferedFile::flush() {
|
||||||
|
if (!file_)
|
||||||
|
return;
|
||||||
|
int result = FMT_SYSTEM(fflush(file_));
|
||||||
|
if (result != 0)
|
||||||
|
throw SystemError(errno, "cannot flush file");
|
||||||
|
}
|
||||||
|
|
||||||
|
void fmt::BufferedFile::write_raw(fmt::StringRef str) {
|
||||||
|
if (!file_)
|
||||||
|
return;
|
||||||
|
std::size_t result = FMT_SYSTEM(fwrite(str.c_str(), str.size(), 1, file_));
|
||||||
|
if (result < str.size()) {
|
||||||
|
// FIXME: According to ```man fwrite```, fwrite won't set errno at all
|
||||||
|
throw SystemError(errno, "failed to write raw string, only {} character(s) written", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fmt::BufferedFile::write_raw(char c) {
|
||||||
|
if (!file_)
|
||||||
|
return;
|
||||||
|
int result = FMT_SYSTEM(fputc(c, file_));
|
||||||
|
if (result == EOF)
|
||||||
|
throw SystemError(errno, "failed to write '{}'", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Implementations of fmt::File
|
||||||
|
|
||||||
fmt::File::File(fmt::StringRef path, int oflag) {
|
fmt::File::File(fmt::StringRef path, int oflag) {
|
||||||
int mode = S_IRUSR | S_IWUSR;
|
int mode = S_IRUSR | S_IWUSR;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -114,7 +145,7 @@ fmt::File::File(fmt::StringRef path, int oflag) {
|
|||||||
throw SystemError(errno, "cannot open file {}", path);
|
throw SystemError(errno, "cannot open file {}", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::File::~File() FMT_NOEXCEPT(true) {
|
fmt::File::~File() FMT_NOEXCEPT {
|
||||||
// Don't retry close in case of EINTR!
|
// Don't retry close in case of EINTR!
|
||||||
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
|
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
|
||||||
if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
|
if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
|
||||||
@ -134,13 +165,13 @@ void fmt::File::close() {
|
|||||||
|
|
||||||
fmt::LongLong fmt::File::size() const {
|
fmt::LongLong fmt::File::size() const {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
LARGE_INTEGER size = {};
|
LARGE_INTEGER filesize;
|
||||||
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
|
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
|
||||||
if (!FMT_SYSTEM(GetFileSizeEx(handle, &size)))
|
if (!FMT_SYSTEM(GetFileSizeEx(handle, &filesize)))
|
||||||
throw WindowsError(GetLastError(), "cannot get file size");
|
throw WindowsError(GetLastError(), "cannot get file size");
|
||||||
FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(size.QuadPart),
|
FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(filesize.QuadPart),
|
||||||
"return type of File::size is not large enough");
|
"return type of File::size is not large enough");
|
||||||
return size.QuadPart;
|
return filesize.QuadPart;
|
||||||
#else
|
#else
|
||||||
typedef struct stat Stat;
|
typedef struct stat Stat;
|
||||||
Stat file_stat = Stat();
|
Stat file_stat = Stat();
|
||||||
@ -186,7 +217,7 @@ void fmt::File::dup2(int fd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fmt::File::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT(true) {
|
void fmt::File::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
|
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
|
||||||
if (result == -1)
|
if (result == -1)
|
||||||
@ -226,9 +257,10 @@ fmt::BufferedFile fmt::File::fdopen(const char *mode) {
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long fmt::getpagesize() {
|
long fmt::getpagesize() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
SYSTEM_INFO si = {};
|
SYSTEM_INFO si;
|
||||||
GetSystemInfo(&si);
|
GetSystemInfo(&si);
|
||||||
return si.dwPageSize;
|
return si.dwPageSize;
|
||||||
#else
|
#else
|
||||||
|
|||||||
61
posix.h
61
posix.h
@ -53,7 +53,7 @@
|
|||||||
#ifdef FMT_SYSTEM
|
#ifdef FMT_SYSTEM
|
||||||
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
||||||
#else
|
#else
|
||||||
# define FMT_SYSTEM(call) call
|
# define FMT_SYSTEM(call) ::call
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
// Fix warnings about deprecated symbols.
|
// Fix warnings about deprecated symbols.
|
||||||
# define FMT_POSIX_CALL(call) ::_##call
|
# define FMT_POSIX_CALL(call) ::_##call
|
||||||
@ -68,7 +68,7 @@
|
|||||||
# define FMT_UNUSED
|
# define FMT_UNUSED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_USE_STATIC_ASSERT
|
#if FMT_USE_STATIC_ASSERT || (defined _MSC_VER && _MSC_VER >= 1700) || FMT_HAS_CPP_ATTRIBUTE(cxx_static_assert) || (__cplusplus >= 201103L && FMT_GCC_VERSION >= 403)
|
||||||
# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
|
# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
|
||||||
#else
|
#else
|
||||||
# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
|
# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
|
||||||
@ -97,9 +97,9 @@ class ErrorCode {
|
|||||||
int value_;
|
int value_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ErrorCode(int value = 0) FMT_NOEXCEPT(true) : value_(value) {}
|
explicit ErrorCode(int value = 0) FMT_NOEXCEPT : value_(value) {}
|
||||||
|
|
||||||
int get() const FMT_NOEXCEPT(true) { return value_; }
|
int get() const FMT_NOEXCEPT { return value_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// A buffered file.
|
// A buffered file.
|
||||||
@ -113,10 +113,10 @@ class BufferedFile {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructs a BufferedFile object which doesn't represent any file.
|
// Constructs a BufferedFile object which doesn't represent any file.
|
||||||
BufferedFile() FMT_NOEXCEPT(true) : file_(0) {}
|
BufferedFile() FMT_NOEXCEPT : file_(0) {}
|
||||||
|
|
||||||
// Destroys the object closing the file it represents if any.
|
// Destroys the object closing the file it represents if any.
|
||||||
~BufferedFile() FMT_NOEXCEPT(true);
|
~BufferedFile() FMT_NOEXCEPT;
|
||||||
|
|
||||||
#if !FMT_USE_RVALUE_REFERENCES
|
#if !FMT_USE_RVALUE_REFERENCES
|
||||||
// Emulate a move constructor and a move assignment operator if rvalue
|
// Emulate a move constructor and a move assignment operator if rvalue
|
||||||
@ -131,10 +131,10 @@ class BufferedFile {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// A "move constructor" for moving from a temporary.
|
// A "move constructor" for moving from a temporary.
|
||||||
BufferedFile(Proxy p) FMT_NOEXCEPT(true) : file_(p.file) {}
|
BufferedFile(Proxy p) FMT_NOEXCEPT : file_(p.file) {}
|
||||||
|
|
||||||
// A "move constructor" for for moving from an lvalue.
|
// A "move constructor" for for moving from an lvalue.
|
||||||
BufferedFile(BufferedFile &f) FMT_NOEXCEPT(true) : file_(f.file_) {
|
BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) {
|
||||||
f.file_ = 0;
|
f.file_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ public:
|
|||||||
|
|
||||||
// Returns a proxy object for moving from a temporary:
|
// Returns a proxy object for moving from a temporary:
|
||||||
// BufferedFile file = BufferedFile(...);
|
// BufferedFile file = BufferedFile(...);
|
||||||
operator Proxy() FMT_NOEXCEPT(true) {
|
operator Proxy() FMT_NOEXCEPT {
|
||||||
Proxy p = {file_};
|
Proxy p = {file_};
|
||||||
file_ = 0;
|
file_ = 0;
|
||||||
return p;
|
return p;
|
||||||
@ -166,7 +166,7 @@ public:
|
|||||||
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
|
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT(true) : file_(other.file_) {
|
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) {
|
||||||
other.file_ = 0;
|
other.file_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,22 +181,41 @@ public:
|
|||||||
// Opens a file.
|
// Opens a file.
|
||||||
BufferedFile(fmt::StringRef filename, fmt::StringRef mode);
|
BufferedFile(fmt::StringRef filename, fmt::StringRef mode);
|
||||||
|
|
||||||
|
// Gets whether a file is opened
|
||||||
|
bool is_open() const FMT_NOEXCEPT { return file_ != 0; }
|
||||||
|
|
||||||
// Closes the file.
|
// Closes the file.
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
// Returns the pointer to a FILE object representing this file.
|
// Returns the pointer to a FILE object representing this file.
|
||||||
FILE *get() const { return file_; }
|
FILE *get() const FMT_NOEXCEPT { return file_; }
|
||||||
|
|
||||||
|
// Gets the file number of a file
|
||||||
int fileno() const;
|
int fileno() const;
|
||||||
|
|
||||||
|
// Flushes the buffer of a file
|
||||||
|
void flush(); // FIXME: Should be const?
|
||||||
|
|
||||||
|
// Writes raw string without formatting
|
||||||
|
void write_raw(fmt::StringRef str);
|
||||||
|
// Writes a single charactor without formatting
|
||||||
|
void write_raw(char c);
|
||||||
|
|
||||||
void print(fmt::StringRef format_str, const ArgList &args) {
|
void print(fmt::StringRef format_str, const ArgList &args) {
|
||||||
fmt::print(file_, format_str, args);
|
fmt::print(file_, format_str, args);
|
||||||
}
|
}
|
||||||
|
void printf(fmt::StringRef format_str, const ArgList &args) {
|
||||||
|
fmt::fprintf(file_, format_str, args);
|
||||||
|
}
|
||||||
|
void println() {
|
||||||
|
write_raw('\n');
|
||||||
|
}
|
||||||
FMT_VARIADIC(void, print, fmt::StringRef)
|
FMT_VARIADIC(void, print, fmt::StringRef)
|
||||||
|
FMT_VARIADIC(void, printf, fmt::StringRef)
|
||||||
};
|
};
|
||||||
|
|
||||||
// A file. Closed file is represented by a File object with descriptor -1.
|
// A file. Closed file is represented by a File object with descriptor -1.
|
||||||
// Methods that are not declared with FMT_NOEXCEPT(true) may throw
|
// Methods that are not declared with FMT_NOEXCEPT may throw
|
||||||
// fmt::SystemError in case of failure. Note that some errors such as
|
// fmt::SystemError in case of failure. Note that some errors such as
|
||||||
// closing the file multiple times will cause a crash on Windows rather
|
// closing the file multiple times will cause a crash on Windows rather
|
||||||
// than an exception. You can get standard behavior by overriding the
|
// than an exception. You can get standard behavior by overriding the
|
||||||
@ -217,7 +236,7 @@ class File {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Constructs a File object which doesn't represent any file.
|
// Constructs a File object which doesn't represent any file.
|
||||||
File() FMT_NOEXCEPT(true) : fd_(-1) {}
|
File() FMT_NOEXCEPT : fd_(-1) {}
|
||||||
|
|
||||||
// Opens a file and constructs a File object representing this file.
|
// Opens a file and constructs a File object representing this file.
|
||||||
File(fmt::StringRef path, int oflag);
|
File(fmt::StringRef path, int oflag);
|
||||||
@ -235,10 +254,10 @@ class File {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// A "move constructor" for moving from a temporary.
|
// A "move constructor" for moving from a temporary.
|
||||||
File(Proxy p) FMT_NOEXCEPT(true) : fd_(p.fd) {}
|
File(Proxy p) FMT_NOEXCEPT : fd_(p.fd) {}
|
||||||
|
|
||||||
// A "move constructor" for for moving from an lvalue.
|
// A "move constructor" for for moving from an lvalue.
|
||||||
File(File &other) FMT_NOEXCEPT(true) : fd_(other.fd_) {
|
File(File &other) FMT_NOEXCEPT : fd_(other.fd_) {
|
||||||
other.fd_ = -1;
|
other.fd_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +278,7 @@ class File {
|
|||||||
|
|
||||||
// Returns a proxy object for moving from a temporary:
|
// Returns a proxy object for moving from a temporary:
|
||||||
// File file = File(...);
|
// File file = File(...);
|
||||||
operator Proxy() FMT_NOEXCEPT(true) {
|
operator Proxy() FMT_NOEXCEPT {
|
||||||
Proxy p = {fd_};
|
Proxy p = {fd_};
|
||||||
fd_ = -1;
|
fd_ = -1;
|
||||||
return p;
|
return p;
|
||||||
@ -270,7 +289,7 @@ class File {
|
|||||||
FMT_DISALLOW_COPY_AND_ASSIGN(File);
|
FMT_DISALLOW_COPY_AND_ASSIGN(File);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
File(File &&other) FMT_NOEXCEPT(true) : fd_(other.fd_) {
|
File(File &&other) FMT_NOEXCEPT : fd_(other.fd_) {
|
||||||
other.fd_ = -1;
|
other.fd_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,10 +302,10 @@ class File {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Destroys the object closing the file it represents if any.
|
// Destroys the object closing the file it represents if any.
|
||||||
~File() FMT_NOEXCEPT(true);
|
~File() FMT_NOEXCEPT;
|
||||||
|
|
||||||
// Returns the file descriptor.
|
// Returns the file descriptor.
|
||||||
int descriptor() const FMT_NOEXCEPT(true) { return fd_; }
|
int descriptor() const FMT_NOEXCEPT { return fd_; }
|
||||||
|
|
||||||
// Closes the file.
|
// Closes the file.
|
||||||
void close();
|
void close();
|
||||||
@ -310,7 +329,7 @@ class File {
|
|||||||
|
|
||||||
// Makes fd be the copy of this file descriptor, closing fd first if
|
// Makes fd be the copy of this file descriptor, closing fd first if
|
||||||
// necessary.
|
// necessary.
|
||||||
void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT(true);
|
void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
|
||||||
|
|
||||||
// Creates a pipe setting up read_end and write_end file objects for reading
|
// Creates a pipe setting up read_end and write_end file objects for reading
|
||||||
// and writing respectively.
|
// and writing respectively.
|
||||||
|
|||||||
@ -19,7 +19,7 @@ add_fmt_test(format-test)
|
|||||||
add_fmt_test(format-impl-test CUSTOM_LINK)
|
add_fmt_test(format-impl-test CUSTOM_LINK)
|
||||||
add_fmt_test(printf-test)
|
add_fmt_test(printf-test)
|
||||||
foreach (target format-test printf-test)
|
foreach (target format-test printf-test)
|
||||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
set_target_properties(${target} PROPERTIES COMPILE_FLAGS
|
set_target_properties(${target} PROPERTIES COMPILE_FLAGS
|
||||||
"-Wall -Wextra -pedantic -Wno-long-long -Wno-variadic-macros")
|
"-Wall -Wextra -pedantic -Wno-long-long -Wno-variadic-macros")
|
||||||
endif ()
|
endif ()
|
||||||
@ -64,12 +64,14 @@ set_target_properties(header-only-test
|
|||||||
PROPERTIES COMPILE_DEFINITIONS "FMT_HEADER_ONLY=1")
|
PROPERTIES COMPILE_DEFINITIONS "FMT_HEADER_ONLY=1")
|
||||||
target_link_libraries(header-only-test gmock)
|
target_link_libraries(header-only-test gmock)
|
||||||
|
|
||||||
# Test that the library can be compiled with exceptions disabled.
|
if (NOT CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||||
check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG)
|
# Test that the library can be compiled with exceptions disabled.
|
||||||
if (HAVE_FNO_EXCEPTIONS_FLAG)
|
check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG)
|
||||||
add_library(noexception-test STATIC ../format.cc)
|
if (HAVE_FNO_EXCEPTIONS_FLAG)
|
||||||
set_target_properties(noexception-test
|
add_library(noexception-test STATIC ../format.cc)
|
||||||
PROPERTIES COMPILE_FLAGS -fno-exceptions)
|
set_target_properties(noexception-test
|
||||||
|
PROPERTIES COMPILE_FLAGS -fno-exceptions)
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_test(compile-test ${CMAKE_CTEST_COMMAND}
|
add_test(compile-test ${CMAKE_CTEST_COMMAND}
|
||||||
|
|||||||
@ -62,7 +62,7 @@ OutputRedirect::OutputRedirect(FILE *file) : file_(file) {
|
|||||||
write_end.dup2(fd);
|
write_end.dup2(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputRedirect::~OutputRedirect() FMT_NOEXCEPT(true) {
|
OutputRedirect::~OutputRedirect() FMT_NOEXCEPT {
|
||||||
try {
|
try {
|
||||||
restore();
|
restore();
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
|
|||||||
@ -104,7 +104,7 @@ class OutputRedirect {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit OutputRedirect(FILE *file);
|
explicit OutputRedirect(FILE *file);
|
||||||
~OutputRedirect() FMT_NOEXCEPT(true);
|
~OutputRedirect() FMT_NOEXCEPT;
|
||||||
|
|
||||||
// Restores the original file, reads output from the pipe into a string
|
// Restores the original file, reads output from the pipe into a string
|
||||||
// and returns it.
|
// and returns it.
|
||||||
|
|||||||
@ -178,6 +178,18 @@ int test::fileno(FILE *stream) {
|
|||||||
return ::FMT_POSIX(fileno(stream));
|
return ::FMT_POSIX(fileno(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test::fflush(FILE *stream) {
|
||||||
|
return ::fflush(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test::fwrite(const void *str, size_t size, size_t count, FILE *stream) {
|
||||||
|
return ::fwrite(str, size, count, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test::fputc(int ch, FILE *stream) {
|
||||||
|
return ::fputc(ch, stream);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# define EXPECT_RETRY(statement, func, message) \
|
# define EXPECT_RETRY(statement, func, message) \
|
||||||
func##_count = 1; \
|
func##_count = 1; \
|
||||||
|
|||||||
@ -73,6 +73,10 @@ int pipe(int *pfds, unsigned psize, int textmode);
|
|||||||
FILE *fopen(const char *filename, const char *mode);
|
FILE *fopen(const char *filename, const char *mode);
|
||||||
int fclose(FILE *stream);
|
int fclose(FILE *stream);
|
||||||
int fileno(FILE *stream);
|
int fileno(FILE *stream);
|
||||||
|
int fflush(FILE *stream);
|
||||||
|
|
||||||
|
int fwrite(const void *str, size_t size, size_t count, FILE *stream);
|
||||||
|
int fputc(int ch, FILE *stream);
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
|
||||||
|
|||||||
@ -699,8 +699,7 @@ void test_count_digits() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(UtilTest, StringRef) {
|
TEST(UtilTest, StringRef) {
|
||||||
char space[100];
|
char space[100] = "some string";
|
||||||
std::strcpy(space, "some string");
|
|
||||||
EXPECT_EQ(sizeof("some string") - 1, StringRef(space).size());
|
EXPECT_EQ(sizeof("some string") - 1, StringRef(space).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user