From 22e42a66f436719466a52a8219d2bb851ddf5303 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Fri, 11 May 2018 14:43:01 +0300 Subject: [PATCH 01/15] Add a _lot_ more warnings to FMT_PEDANTIC Fix these warnings --- CMakeLists.txt | 29 ++++++++++- include/fmt/core.h | 28 +++++++---- include/fmt/format-inl.h | 27 ++++++++++- include/fmt/format.h | 101 +++++++++++++++++++++++---------------- src/posix.cc | 2 +- test/gtest-extra-test.cc | 24 ++++++---- test/posix-test.cc | 2 +- test/util-test.cc | 4 +- 8 files changed, 149 insertions(+), 68 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 045004a269fa..3f65a6a4ef52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,8 +59,33 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} include(cxx14) -if (CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) - set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -Wshadow -pedantic) +if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(PEDANTIC_COMPILE_FLAGS -pedantic-errors -Wall -Wextra -pedantic + -Wold-style-cast -Wfloat-equal -Wlogical-op -Wundef + -Wredundant-decls -Wshadow -Wwrite-strings -Wpointer-arith + -Wcast-qual -Wformat=2 -Wmissing-include-dirs + -Wcast-align -Wnon-virtual-dtor + -Wctor-dtor-privacy -Wdisabled-optimization + -Winvalid-pch -Wmissing-declarations -Woverloaded-virtual) + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) + set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept) + endif () + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wdouble-promotion + -Wtrampolines -Wzero-as-null-pointer-constant -Wuseless-cast + -Wvector-operation-performance -Wsized-deallocation) + endif () + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2 + -Wnull-dereference -Wduplicated-cond) + endif () +endif () + +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(PEDANTIC_COMPILE_FLAGS -Weverything -Wpedantic + -Wno-weak-vtables -Wno-padded -Wno-gnu-statement-expression + -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-reserved-id-macro + -Wno-global-constructors -Wno-disabled-macro-expansion) endif () if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio") diff --git a/include/fmt/core.h b/include/fmt/core.h index 66597eedbf8a..d0f63feb7a7a 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -30,10 +30,10 @@ # define FMT_HAS_INCLUDE(x) 0 #endif -#if defined(__GNUC__) && !defined(__clang__) -# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#ifdef __has_cpp_attribute +# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) #else -# define FMT_GCC_VERSION 0 +# define FMT_HAS_CPP_ATTRIBUTE(x) 0 #endif #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) @@ -42,12 +42,6 @@ # define FMT_HAS_GXX_CXX11 0 #endif -#ifdef _MSC_VER -# define FMT_MSC_VER _MSC_VER -#else -# define FMT_MSC_VER 0 -#endif - // Check if relaxed c++14 constexpr is supported. // GCC doesn't allow throw in constexpr until version 6 (bug 67371). #ifndef FMT_USE_CONSTEXPR @@ -94,6 +88,12 @@ # define FMT_USE_NULLPTR 0 #endif +#if FMT_HAS_CPP_ATTRIBUTE(noreturn) +# define FMT_NORETURN [[noreturn]] +#else +# define FMT_NORETURN /*noreturn*/ +#endif + // Check if exceptions are disabled. #if defined(__GNUC__) && !defined(__EXCEPTIONS) # define FMT_EXCEPTIONS 0 @@ -557,6 +557,11 @@ struct typed_value : value { template FMT_CONSTEXPR basic_format_arg make_arg(const T &value); +#if FMT_GCC_VERSION +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuseless-cast" +#endif + #define FMT_MAKE_VALUE(TAG, ArgType, ValueType) \ template \ FMT_CONSTEXPR typed_value make_value(ArgType val) { \ @@ -624,6 +629,11 @@ FMT_MAKE_VALUE(pointer_type, const void*, const void*) FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void*) #endif +#if FMT_GCC_VERSION +// -Wuseless-cast +#pragma GCC diagnostic pop +#endif + // Formatting of arbitrary pointers is disallowed. If you want to output a // pointer cast it to "void *" or "const void *". In particular, this forbids // formatting of "[const] volatile char *" which is printed as bool by diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index f5c26d2f3f44..fad31909a7d9 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -74,8 +74,6 @@ FMT_BEGIN_NAMESPACE FMT_FUNC format_error::~format_error() throw() {} FMT_FUNC system_error::~system_error() FMT_DTOR_NOEXCEPT {} -namespace { - #ifndef _MSC_VER # define FMT_SNPRINTF snprintf #else // _MSC_VER @@ -122,6 +120,11 @@ int safe_strerror( // A noop assignment operator to avoid bogus warnings. void operator=(const StrError &) {} +#if FMT_CLANG_VERSION +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-member-function" +#endif + // Handle the result of XSI-compliant version of strerror_r. int handle(int result) { // glibc versions before 2.13 return result in errno. @@ -156,6 +159,10 @@ int safe_strerror( return errno; } +#if FMT_CLANG_VERSION +#pragma clang diagnostic pop +#endif + public: StrError(int err_code, char *&buf, std::size_t buf_size) : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} @@ -221,6 +228,11 @@ FMT_FUNC void system_error::init( } namespace internal { +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif + template int char_traits::format_float( char *buffer, std::size_t size, const char *format, @@ -249,6 +261,10 @@ int char_traits::format_float( FMT_SWPRINTF(buffer, size, format, width, precision, value); } +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + template const char basic_data::DIGITS[] = "0001020304050607080910111213141516171819" @@ -468,9 +484,16 @@ void basic_fixed_buffer::grow(std::size_t) { FMT_THROW(std::runtime_error("buffer overflow")); } +#if FMT_CLANG_VERSION +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-noreturn" +#endif FMT_FUNC void internal::error_handler::on_error(const char *message) { FMT_THROW(format_error(message)); } +#if FMT_CLANG_VERSION +#pragma clang diagnostic pop +#endif FMT_FUNC void report_system_error( int error_code, fmt::string_view message) FMT_NOEXCEPT { diff --git a/include/fmt/format.h b/include/fmt/format.h index 07c644aa8a2b..215510ac9e9f 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -37,63 +37,69 @@ #include #include -#include "core.h" +#if defined(__GNUC__) && !defined(__clang__) +# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#else +# define FMT_GCC_VERSION 0 +#endif -#ifdef _SECURE_SCL -# define FMT_SECURE_SCL _SECURE_SCL +#ifdef __clang__ +# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) #else -# define FMT_SECURE_SCL 0 +# define FMT_CLANG_VERSION 0 #endif -#if FMT_SECURE_SCL -# include +#if defined(__INTEL_COMPILER) +# define FMT_ICC_VERSION __INTEL_COMPILER +#elif defined(__ICL) +# define FMT_ICC_VERSION __ICL #endif -#ifdef __has_builtin -# define FMT_HAS_BUILTIN(x) __has_builtin(x) +#ifdef _MSC_VER +# define FMT_MSC_VER _MSC_VER #else -# define FMT_HAS_BUILTIN(x) 0 +# define FMT_MSC_VER 0 #endif -#ifdef __GNUC__ -# if FMT_GCC_VERSION >= 406 -# pragma GCC diagnostic push +#if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION +# pragma GCC diagnostic push // Disable the warning about declaration shadowing because it affects too // many valid cases. -# pragma GCC diagnostic ignored "-Wshadow" +# pragma GCC diagnostic ignored "-Wshadow" // Disable the warning about implicit conversions that may change the sign of // an integer; silencing it otherwise would require many explicit casts. -# pragma GCC diagnostic ignored "-Wsign-conversion" -# endif +# pragma GCC diagnostic ignored "-Wsign-conversion" #endif -#ifdef __clang__ -# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) -#endif - -#if defined(__INTEL_COMPILER) -# define FMT_ICC_VERSION __INTEL_COMPILER -#elif defined(__ICL) -# define FMT_ICC_VERSION __ICL -#endif - -#if defined(__clang__) && !defined(FMT_ICC_VERSION) +#if FMT_CLANG_VERSION && !defined(FMT_ICC_VERSION) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdocumentation-unknown-command" # pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template" -# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" #endif -#ifdef __GNUC_LIBSTD__ -# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) +#include "core.h" + +#ifdef _SECURE_SCL +# define FMT_SECURE_SCL _SECURE_SCL +#else +# define FMT_SECURE_SCL 0 +#endif + +#if FMT_SECURE_SCL +# include #endif -#ifdef __has_cpp_attribute -# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#ifdef __has_builtin +# define FMT_HAS_BUILTIN(x) __has_builtin(x) #else -# define FMT_HAS_CPP_ATTRIBUTE(x) 0 +# define FMT_HAS_BUILTIN(x) 0 +#endif + +#ifdef __GNUC_LIBSTD__ +# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) #endif #ifndef FMT_THROW @@ -115,9 +121,8 @@ # endif #endif -#if FMT_USE_USER_DEFINED_LITERALS && \ - ((FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L) || \ - (defined(FMT_CLANG_VERSION) && FMT_CLANG_VERSION >= 304)) +#if FMT_USE_USER_DEFINED_LITERALS && __cplusplus >= 201402L && \ + (FMT_GCC_VERSION >= 600 || FMT_CLANG_VERSION >= 304) # define FMT_UDL_TEMPLATE 1 #else # define FMT_UDL_TEMPLATE 0 @@ -126,7 +131,8 @@ #ifndef FMT_USE_EXTERN_TEMPLATES # ifndef FMT_HEADER_ONLY # define FMT_USE_EXTERN_TEMPLATES \ - (FMT_CLANG_VERSION >= 209 || (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11)) + ((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \ + (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11)) # else # define FMT_USE_EXTERN_TEMPLATES 0 # endif @@ -134,6 +140,14 @@ #if FMT_HAS_GXX_CXX11 || FMT_HAS_FEATURE(cxx_trailing_return) || FMT_MSC_VER >= 1600 # define FMT_USE_TRAILING_RETURN 1 +#else +# define FMT_USE_TRAILING_RETURN 0 +#endif + +#if FMT_HAS_GXX_CXX11 || FMT_HAS_FEATURE(cxx_rvalue_references) || FMT_MSC_VER >= 1600 +# define FMT_USE_RVALUE_REFERENCES 1 +#else +# define FMT_USE_RVALUE_REFERENCES 0 #endif // __builtin_clz is broken in clang with Microsoft CodeGen: @@ -380,8 +394,6 @@ class format_error : public std::runtime_error { explicit format_error(const std::string &message) : std::runtime_error(message) {} - - FMT_API ~format_error() throw(); }; namespace internal { @@ -2306,8 +2318,6 @@ class system_error : public std::runtime_error { init(error_code, message, make_format_args(args...)); } - FMT_API ~system_error() FMT_DTOR_NOEXCEPT; - int error_code() const { return error_code_; } }; @@ -2542,11 +2552,18 @@ class basic_writer { }; void on_num() { + #if FMT_CLANG_VERSION + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wundefined-func-template" + #endif unsigned num_digits = internal::count_digits(abs_value); char_type sep = internal::thousands_sep(writer.locale_.get()); unsigned size = num_digits + SEP_SIZE * ((num_digits - 1) / 3); writer.write_int(size, get_prefix(), spec, num_writer{abs_value, size, sep}); + #if FMT_CLANG_VERSION + #pragma clang diagnostic pop + #endif } void on_error() { @@ -3647,11 +3664,11 @@ FMT_END_NAMESPACE #endif // Restore warnings. -#if FMT_GCC_VERSION >= 406 +#if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION # pragma GCC diagnostic pop #endif -#if defined(__clang__) && !defined(FMT_ICC_VERSION) +#if FMT_CLANG_VERSION && !defined(FMT_ICC_VERSION) # pragma clang diagnostic pop #endif diff --git a/src/posix.cc b/src/posix.cc index bcdab3244efa..452d49f5f772 100644 --- a/src/posix.cc +++ b/src/posix.cc @@ -6,7 +6,7 @@ // For the license information refer to format.h. // Disable bogus MSVC warnings. -#ifndef _CRT_SECURE_NO_WARNINGS +#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER) # define _CRT_SECURE_NO_WARNINGS #endif diff --git a/test/gtest-extra-test.cc b/test/gtest-extra-test.cc index 2043f5499aae..53f0a0d6c882 100644 --- a/test/gtest-extra-test.cc +++ b/test/gtest-extra-test.cc @@ -195,33 +195,39 @@ TEST(ExpectSystemErrorTest, DoesNotGenerateUnreachableCodeWarning) { } TEST(AssertionSyntaxTest, ExceptionAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) + if (::testing::internal::AlwaysFalse()) { EXPECT_THROW_MSG(do_nothing(), std::exception, ""); + } - if (::testing::internal::AlwaysTrue()) + if (::testing::internal::AlwaysTrue()) { EXPECT_THROW_MSG(throw_exception(), std::exception, "test"); - else + } else { do_nothing(); + } } TEST(AssertionSyntaxTest, SystemErrorAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) + if (::testing::internal::AlwaysFalse()) { EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, ""); + } - if (::testing::internal::AlwaysTrue()) + if (::testing::internal::AlwaysTrue()) { EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test"); - else + } else { do_nothing(); + } } TEST(AssertionSyntaxTest, WriteAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) + if (::testing::internal::AlwaysFalse()) { EXPECT_WRITE(stdout, std::printf("x"), "x"); + } - if (::testing::internal::AlwaysTrue()) + if (::testing::internal::AlwaysTrue()) { EXPECT_WRITE(stdout, std::printf("x"), "x"); - else + } else { do_nothing(); + } } // Tests EXPECT_THROW_MSG. diff --git a/test/posix-test.cc b/test/posix-test.cc index d6b1953c4200..6e0d08c63ec9 100644 --- a/test/posix-test.cc +++ b/test/posix-test.cc @@ -153,7 +153,7 @@ TEST(BufferedFileTest, Fileno) { EXPECT_DEATH_IF_SUPPORTED({ try { f.fileno(); - } catch (fmt::system_error) { + } catch (const fmt::system_error&) { std::exit(1); } }, ""); diff --git a/test/util-test.cc b/test/util-test.cc index 544d933d06fc..a9329a384985 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -402,7 +402,7 @@ TEST(UtilTest, BitCast) { uint32_t u[2]; }; auto s = fmt::internal::bit_cast(uint64_t(42)); - EXPECT_EQ(fmt::internal::bit_cast(s), 42); + EXPECT_EQ(fmt::internal::bit_cast(s), 42ull); s = fmt::internal::bit_cast(uint64_t(~0ull)); EXPECT_EQ(fmt::internal::bit_cast(s), ~0ull); } @@ -765,7 +765,7 @@ TEST(UtilTest, FormatSystemError) { try { std::allocator alloc; alloc.deallocate(alloc.allocate(max_size), max_size); - } catch (std::bad_alloc) { + } catch (const std::bad_alloc&) { throws_on_alloc = true; } if (!throws_on_alloc) { From 97e1271e5eab87b4f5b71b5d7cd771d95fbc3916 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Fri, 11 May 2018 16:24:38 +0300 Subject: [PATCH 02/15] Add more compilers to CI Fix (some) of the compiler errors with them --- .travis.yml | 99 ++++++++++++++++++++++++++++++++-------- CMakeLists.txt | 3 +- include/fmt/core.h | 6 +-- include/fmt/format-inl.h | 10 +--- include/fmt/format.h | 2 +- 5 files changed, 88 insertions(+), 32 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4388dd576ff0..8443e5a03ee8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,19 @@ language: cpp dist: trusty -sudo: required # the doc target uses sudo to install dependencies +sudo: false -os: - - linux - - osx +os: linux + +git: + depth: 1 + +addons: + apt: + update: true + sources: &apt_sources + - ubuntu-toolchain-r-test + packages: + - g++-6 env: global: @@ -12,16 +21,65 @@ env: a1eovNn4uol9won7ghr67eD3/59oeESN+G9bWE+ecI1V6yRseG9whniGhIpC/YfMW/Qz5I 5sxSmFjaw9bxCISNwUIrL1O5x2AmRYTnFcXk4dFsUvlZg+WeF/aKyBYCNRM8C2ndbBmtAO o1F2EwFbiso0EmtzhAPs19ujiVxkLn4= - matrix: - - BUILD=Doc - - BUILD=Debug STANDARD=14 - - BUILD=Release STANDARD=14 matrix: exclude: - - os: osx - env: BUILD=Doc + - env: TRAVIS_EMPTY_JOB_WORKAROUND=true include: + # Documentation + - env: CXX_COMPILER=g++-6 BUILD=Doc + sudo: required + compiler: gcc + # g++ 6 on Linux with C++14 + - env: CXX_COMPILER=g++-6 BUILD=Debug STANDARD=14 + compiler: gcc + - env: CXX_COMPILER=g++-6 BUILD=Release STANDARD=14 + compiler: gcc + # Apple clang on OS X with C++14 + - env: BUILD=Debug STANDARD=14 + compiler: clang + os: osx + - env: BUILD=Release STANDARD=14 + compiler: clang + os: osx + # clang 6.0 on Linux with C++14 + - env: CXX_COMPILER=clang++-6.0 BUILD=Debug STANDARD=14 + compiler: clang + addons: + apt: + update: true + packages: + - clang-6.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty + - llvm-toolchain-trusty-6.0 + # clang 4.0 on Linux with C++14 + - env: CXX_COMPILER=clang++-4.0 BUILD=Debug STANDARD=11 + compiler: clang + addons: + apt: + update: true + packages: + - clang-4.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty + - llvm-toolchain-trusty-4.0 + # g++ 4.8 on Linux with C++11 + - env: CXX_COMPILER=g++-4.8 BUILD=Debug STANDARD=11 + compiler: gcc + # g++ 4.4 on Linux with C++11 + - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=0x + compiler: gcc + addons: + apt: + update: true + packages: + - g++-4.4 + sources: + - ubuntu-toolchain-r-test + # Android - language: android android: components: @@ -51,17 +109,20 @@ matrix: after_success: - cd ${TRAVIS_BUILD_DIR} - tree ./libs + allow_failures: + # Errors + - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=0x + compiler: gcc -# Install gcc-6 for extended constexpr support. -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-6 +install: + - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" + - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR} + + - cd ${TRAVIS_BUILD_DIR} -before_install: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=g++-6; fi +before_script: + - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then export CXX=${CXX_COMPILER}; fi + - ${CXX} --version script: - support/travis-build.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f65a6a4ef52..4156356daf36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") -Wcast-qual -Wformat=2 -Wmissing-include-dirs -Wcast-align -Wnon-virtual-dtor -Wctor-dtor-privacy -Wdisabled-optimization - -Winvalid-pch -Wmissing-declarations -Woverloaded-virtual) + -Winvalid-pch -Wmissing-declarations -Woverloaded-virtual + -Wno-sign-conversion -Wno-shadow) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept) endif () diff --git a/include/fmt/core.h b/include/fmt/core.h index d0f63feb7a7a..820304ffa97b 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -219,7 +219,7 @@ class basic_string_view { #else struct type { const char *data() const { return FMT_NULL; } - size_t size() const { return 0; }; + size_t size() const { return 0; } }; #endif @@ -557,7 +557,7 @@ struct typed_value : value { template FMT_CONSTEXPR basic_format_arg make_arg(const T &value); -#if FMT_GCC_VERSION +#if FMT_GCC_VERSION >= 406 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wuseless-cast" #endif @@ -629,7 +629,7 @@ FMT_MAKE_VALUE(pointer_type, const void*, const void*) FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void*) #endif -#if FMT_GCC_VERSION +#if FMT_GCC_VERSION >= 406 // -Wuseless-cast #pragma GCC diagnostic pop #endif diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index fad31909a7d9..f66a5ff680b3 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -45,12 +45,6 @@ # define FMT_CATCH(x) if (false) #endif -#ifdef __GNUC__ -// Disable the warning about declaration shadowing because it affects too -// many valid cases. -# pragma GCC diagnostic ignored "-Wshadow" -#endif - #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4127) // conditional expression is constant @@ -228,7 +222,7 @@ FMT_FUNC void system_error::init( } namespace internal { -#ifdef __GNUC__ +#if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" #endif @@ -261,7 +255,7 @@ int char_traits::format_float( FMT_SWPRINTF(buffer, size, format, width, precision, value); } -#ifdef __GNUC__ +#if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION #pragma GCC diagnostic pop #endif diff --git a/include/fmt/format.h b/include/fmt/format.h index 215510ac9e9f..ce1347b41d81 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -318,7 +318,7 @@ fp operator*(fp x, fp y); // Compute k such that its cached power c_k = c_k.f * pow(2, c_k.e) satisfies // min_exponent <= c_k.e + e <= min_exponent + 3. inline int compute_cached_power_index(int e, int min_exponent) { - constexpr double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10) + FMT_CONSTEXPR_DECL double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10) return static_cast(std::ceil((min_exponent - e + 63) * one_over_log2_10)); } From 5d7103af4e6fb6c5055d5b0f82d8f3c2aab24bb8 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Fri, 11 May 2018 19:30:05 +0300 Subject: [PATCH 03/15] Enable -Werror on CI Increase warning level on MSVC when compiling with FMT_PEDANTIC --- CMakeLists.txt | 12 ++++++++++++ appveyor.yml | 1 + support/travis-build.py | 4 ++-- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 120000 appveyor.yml diff --git a/CMakeLists.txt b/CMakeLists.txt index 4156356daf36..9d4418e6f32f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2 -Wnull-dereference -Wduplicated-cond) endif () + + set(WERROR_FLAG -Werror) endif () if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") @@ -87,6 +89,13 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") -Wno-weak-vtables -Wno-padded -Wno-gnu-statement-expression -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-reserved-id-macro -Wno-global-constructors -Wno-disabled-macro-expansion) + + set(WERROR_FLAG -Werror) +endif () + +if (MSVC) + set(PEDANTIC_COMPILE_FLAGS /W4) + set(WERROR_FLAG /WX) endif () if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio") @@ -135,6 +144,9 @@ add_library(fmt::fmt ALIAS fmt) # Starting with CMake 3.1 the CXX_STANDARD property can be used instead. # Don't export -std since it may break projects that use other standards. target_compile_options(fmt PRIVATE ${CPP14_FLAG}) +if (FMT_WERROR) + target_compile_options(fmt PRIVATE ${WERROR_FLAG}) +endif () if (FMT_PEDANTIC) target_compile_options(fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS}) endif () diff --git a/appveyor.yml b/appveyor.yml new file mode 120000 index 000000000000..a053ea84d057 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1 @@ +support/appveyor.yml \ No newline at end of file diff --git a/support/travis-build.py b/support/travis-build.py index baefc1d4a23c..ce34b98ac620 100755 --- a/support/travis-build.py +++ b/support/travis-build.py @@ -86,12 +86,12 @@ def install_dependencies(): # Configure library. makedirs_if_not_exist(build_dir) common_cmake_flags = [ - '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build + '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build, ] extra_cmake_flags = [] if standard != '14': extra_cmake_flags = ['-DCMAKE_CXX_FLAGS=-std=c++' + standard] -check_call(['cmake', '-DFMT_DOC=OFF', '-DFMT_PEDANTIC=ON', fmt_dir] + +check_call(['cmake', '-DFMT_DOC=OFF', '-DFMT_PEDANTIC=ON', '-DFMT_WERROR=ON', fmt_dir] + common_cmake_flags + extra_cmake_flags, cwd=build_dir) # Build library. From b49acb3aa8fbaec66020bb5edb7cd3d29943b6a7 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Fri, 11 May 2018 19:45:35 +0300 Subject: [PATCH 04/15] Add VS 2013 and 2015 to Appveyor --- .travis.yml | 2 ++ include/fmt/format.h | 17 +++++++++++--- support/appveyor-build.py | 33 --------------------------- support/appveyor.yml | 47 ++++++++++++++++++++++++++++++--------- 4 files changed, 53 insertions(+), 46 deletions(-) delete mode 100755 support/appveyor-build.py diff --git a/.travis.yml b/.travis.yml index 8443e5a03ee8..6ef03aa78b4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -111,6 +111,8 @@ matrix: - tree ./libs allow_failures: # Errors + - env: CXX_COMPILER=g++-4.8 BUILD=Debug STANDARD=11 + compiler: gcc - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=0x compiler: gcc diff --git a/include/fmt/format.h b/include/fmt/format.h index ce1347b41d81..cd25ef48f4f6 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -49,10 +49,12 @@ # define FMT_CLANG_VERSION 0 #endif -#if defined(__INTEL_COMPILER) +#ifdef __INTEL_COMPILER # define FMT_ICC_VERSION __INTEL_COMPILER #elif defined(__ICL) # define FMT_ICC_VERSION __ICL +#else +# define FMT_ICC_VERSION 0 #endif #ifdef _MSC_VER @@ -73,7 +75,7 @@ # pragma GCC diagnostic ignored "-Wsign-conversion" #endif -#if FMT_CLANG_VERSION && !defined(FMT_ICC_VERSION) +#if FMT_CLANG_VERSION && !FMT_ICC_VERSION # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdocumentation-unknown-command" # pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template" @@ -114,7 +116,7 @@ // For Intel's compiler both it and the system gcc/msc must support UDLs. # if (FMT_HAS_FEATURE(cxx_user_literals) || \ FMT_GCC_VERSION >= 407 || FMT_MSC_VER >= 1900) && \ - (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500) + (!FMT_ICC_VERSION || FMT_ICC_VERSION >= 1500) # define FMT_USE_USER_DEFINED_LITERALS 1 # else # define FMT_USE_USER_DEFINED_LITERALS 0 @@ -1614,6 +1616,11 @@ FMT_CONSTEXPR unsigned parse_nonnegative_int(Iterator &it, ErrorHandler &&eh) { return value; } +#if FMT_MSC_VER +#pragma warning(push) +#pragma warning(disable: 4512) +#endif + template class custom_formatter: public function { private: @@ -1631,6 +1638,10 @@ class custom_formatter: public function { bool operator()(T) const { return false; } }; +#if FMT_MSC_VER +#pragma warning(pop) +#endif + template struct is_integer { enum { diff --git a/support/appveyor-build.py b/support/appveyor-build.py deleted file mode 100755 index cd6324fe20dc..000000000000 --- a/support/appveyor-build.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# Build the project on AppVeyor. - -import os -from subprocess import check_call - -build = os.environ['BUILD'] -config = os.environ['CONFIGURATION'] -platform = os.environ.get('PLATFORM') -path = os.environ['PATH'] -cmake_command = ['cmake', '-DFMT_PEDANTIC=ON', '-DCMAKE_BUILD_TYPE=' + config] -if build == 'mingw': - cmake_command.append('-GMinGW Makefiles') - build_command = ['mingw32-make', '-j4'] - test_command = ['mingw32-make', 'test'] - # Remove the path to Git bin directory from $PATH because it breaks - # MinGW config. - path = path.replace(r'C:\Program Files (x86)\Git\bin', '') - os.environ['PATH'] = r'C:\MinGW\bin;' + path -else: - # Add MSBuild 14.0 to PATH as described in - # http://help.appveyor.com/discussions/problems/2229-v140-not-found-on-vs2105rc. - os.environ['PATH'] = r'C:\Program Files (x86)\MSBuild\15.0\Bin;' + path - generator = 'Visual Studio 15 2017' - if platform == 'x64': - generator += ' Win64' - cmake_command.append('-G' + generator) - build_command = ['cmake', '--build', '.', '--config', config, '--', '/m:4'] - test_command = ['ctest', '-C', config] - -check_call(cmake_command) -check_call(build_command) -check_call(test_command) diff --git a/support/appveyor.yml b/support/appveyor.yml index d7eb8434c125..600d71aaaa19 100644 --- a/support/appveyor.yml +++ b/support/appveyor.yml @@ -1,22 +1,49 @@ -configuration: - - Debug - - Release +configuration: Debug -image: Visual Studio 2017 +clone_depth: 1 + +platform: + - Win32 + - x64 environment: CTEST_OUTPUT_ON_FAILURE: 1 + MSVC_DEFAULT_OPTIONS: ON matrix: - - BUILD: msvc - - BUILD: msvc - PLATFORM: x64 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 + CMAKE_GENERATOR: Visual Studio 12 2013 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + CMAKE_GENERATOR: Visual Studio 14 2015 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + CMAKE_GENERATOR: Visual Studio 15 2017 + +matrix: + allow_failures: + - image: Visual Studio 2013 + +init: + - ps: | + If ($env:Platform -Match "x64") { + $env:CMAKE_GENERATOR_SUFFIX=" Win64" + } before_build: # Workaround for CMake not wanting sh.exe on PATH for MinGW. - - set PATH=%PATH:C:\Program Files\Git\usr\bin;=% + - ps: | + mkdir build + cd build + + cmake -G "$($env:CMAKE_GENERATOR)$($env:CMAKE_GENERATOR_SUFFIX)" -DFMT_WERROR=OFF -DFMT_PEDANTIC=ON -DCMAKE_BUILD_TYPE=$env:CONFIGURATION .. + +build: + project: C:\projects\fmt\build\fmt.sln + parallel: true + verbosity: normal -build_script: - - python support/appveyor-build.py +test_script: + - ps: | + cd build + ctest -C $env:CONFIGURATION on_failure: - appveyor PushArtifact Testing/Temporary/LastTest.log From 710d07882409aa011d3ed66765df28a645443bfd Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Fri, 11 May 2018 21:38:40 +0300 Subject: [PATCH 05/15] Fix Appveyor tests Formatting --- CMakeLists.txt | 4 +++- include/fmt/core.h | 6 +++--- include/fmt/format-inl.h | 18 +++++++++--------- include/fmt/format.h | 21 ++++++++++++++------- support/appveyor.yml | 21 +++++++++++++-------- support/travis-build.py | 2 +- 6 files changed, 43 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d4418e6f32f..eb29eb2ad331 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,9 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(PEDANTIC_COMPILE_FLAGS -Weverything -Wpedantic -Wno-weak-vtables -Wno-padded -Wno-gnu-statement-expression -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-reserved-id-macro - -Wno-global-constructors -Wno-disabled-macro-expansion) + -Wno-global-constructors -Wno-disabled-macro-expansion + -Wno-switch-enum -Wno-documentation-unknown-command + -Wno-gnu-string-literal-operator-template) set(WERROR_FLAG -Werror) endif () diff --git a/include/fmt/core.h b/include/fmt/core.h index 820304ffa97b..17b685a23319 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -558,8 +558,8 @@ template FMT_CONSTEXPR basic_format_arg make_arg(const T &value); #if FMT_GCC_VERSION >= 406 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wuseless-cast" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #define FMT_MAKE_VALUE(TAG, ArgType, ValueType) \ @@ -631,7 +631,7 @@ FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void*) #if FMT_GCC_VERSION >= 406 // -Wuseless-cast -#pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif // Formatting of arbitrary pointers is disallowed. If you want to output a diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index f66a5ff680b3..ac29038c68ea 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -115,8 +115,8 @@ int safe_strerror( void operator=(const StrError &) {} #if FMT_CLANG_VERSION -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-member-function" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunused-member-function" #endif // Handle the result of XSI-compliant version of strerror_r. @@ -154,7 +154,7 @@ int safe_strerror( } #if FMT_CLANG_VERSION -#pragma clang diagnostic pop +# pragma clang diagnostic pop #endif public: @@ -223,8 +223,8 @@ FMT_FUNC void system_error::init( namespace internal { #if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat-nonliteral" #endif template @@ -256,7 +256,7 @@ int char_traits::format_float( } #if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION -#pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif template @@ -479,14 +479,14 @@ void basic_fixed_buffer::grow(std::size_t) { } #if FMT_CLANG_VERSION -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmissing-noreturn" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmissing-noreturn" #endif FMT_FUNC void internal::error_handler::on_error(const char *message) { FMT_THROW(format_error(message)); } #if FMT_CLANG_VERSION -#pragma clang diagnostic pop +# pragma clang diagnostic pop #endif FMT_FUNC void report_system_error( diff --git a/include/fmt/format.h b/include/fmt/format.h index cd25ef48f4f6..f7bfe233095f 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -77,9 +77,16 @@ #if FMT_CLANG_VERSION && !FMT_ICC_VERSION # pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wweak-vtables" +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wgnu-statement-expression" +# pragma clang diagnostic ignored "-Wc++98-compat" +# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +# pragma clang diagnostic ignored "-Wglobal-constructors" +# pragma clang diagnostic ignored "-Wdisabled-macro-expansion" # pragma clang diagnostic ignored "-Wdocumentation-unknown-command" # pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template" -# pragma clang diagnostic ignored "-Wswitch-enum" #endif #include "core.h" @@ -1617,8 +1624,8 @@ FMT_CONSTEXPR unsigned parse_nonnegative_int(Iterator &it, ErrorHandler &&eh) { } #if FMT_MSC_VER -#pragma warning(push) -#pragma warning(disable: 4512) +# pragma warning(push) +# pragma warning(disable: 4512) #endif template @@ -1639,7 +1646,7 @@ class custom_formatter: public function { }; #if FMT_MSC_VER -#pragma warning(pop) +# pragma warning(pop) #endif template @@ -2564,8 +2571,8 @@ class basic_writer { void on_num() { #if FMT_CLANG_VERSION - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundefined-func-template" + # pragma clang diagnostic push + # pragma clang diagnostic ignored "-Wundefined-func-template" #endif unsigned num_digits = internal::count_digits(abs_value); char_type sep = internal::thousands_sep(writer.locale_.get()); @@ -2573,7 +2580,7 @@ class basic_writer { writer.write_int(size, get_prefix(), spec, num_writer{abs_value, size, sep}); #if FMT_CLANG_VERSION - #pragma clang diagnostic pop + # pragma clang diagnostic pop #endif } diff --git a/support/appveyor.yml b/support/appveyor.yml index 600d71aaaa19..cc5ef9a97a7c 100644 --- a/support/appveyor.yml +++ b/support/appveyor.yml @@ -19,7 +19,8 @@ environment: matrix: allow_failures: - - image: Visual Studio 2013 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 + CMAKE_GENERATOR: Visual Studio 12 2013 init: - ps: | @@ -28,12 +29,10 @@ init: } before_build: - # Workaround for CMake not wanting sh.exe on PATH for MinGW. - - ps: | - mkdir build - cd build + - mkdir build + - cd build - cmake -G "$($env:CMAKE_GENERATOR)$($env:CMAKE_GENERATOR_SUFFIX)" -DFMT_WERROR=OFF -DFMT_PEDANTIC=ON -DCMAKE_BUILD_TYPE=$env:CONFIGURATION .. + - ps: cmake -G "$($env:CMAKE_GENERATOR)$($env:CMAKE_GENERATOR_SUFFIX)" -DFMT_WERROR=OFF -DFMT_PEDANTIC=ON -DCMAKE_BUILD_TYPE=Debug .. build: project: C:\projects\fmt\build\fmt.sln @@ -42,8 +41,14 @@ build: test_script: - ps: | - cd build - ctest -C $env:CONFIGURATION + New-Item .\DartConfiguration.tcl -ItemType file + ctest -C Debug -T Test + $XSLInputElement = New-Object System.Xml.Xsl.XslCompiledTransform + $XslInputElement.Load("https://raw.githubusercontent.com/rpavlik/jenkins-ctest-plugin/master/ctest-to-junit.xsl") + $file = $(ls Testing\*\Test.xml) | Select -first 1 + $XSLInputElement.Transform((Resolve-Path $file), (Join-Path (Resolve-Path .) "ctest-to-junit-results.xml")) + $wc = New-Object 'System.Net.WebClient' + $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\ctest-to-junit-results.xml)) on_failure: - appveyor PushArtifact Testing/Temporary/LastTest.log diff --git a/support/travis-build.py b/support/travis-build.py index ce34b98ac620..21fc08712438 100755 --- a/support/travis-build.py +++ b/support/travis-build.py @@ -86,7 +86,7 @@ def install_dependencies(): # Configure library. makedirs_if_not_exist(build_dir) common_cmake_flags = [ - '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build, + '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build ] extra_cmake_flags = [] if standard != '14': From 58991c740443f0985889996d600f7e22f6a246ca Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Sun, 13 May 2018 17:01:28 +0300 Subject: [PATCH 06/15] Implement requested changes Fix some of the MSVC warnings Implement C++11 integer_sequence --- .travis.yml | 13 ++----------- include/fmt/core.h | 39 ++++++++++++++++++++------------------- include/fmt/format-inl.h | 3 +-- include/fmt/format.h | 17 +++++------------ include/fmt/printf.h | 2 -- include/fmt/ranges.h | 36 +++++++++++++++++++++++++++++++++--- include/fmt/time.h | 2 -- support/appveyor.yml | 8 +++++--- test/format-impl-test.cc | 3 +-- test/gtest-extra-test.cc | 24 +++++++++--------------- test/util-test.cc | 3 ++- 11 files changed, 78 insertions(+), 72 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6ef03aa78b4f..3d01de231ccd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,13 +23,10 @@ env: o1F2EwFbiso0EmtzhAPs19ujiVxkLn4= matrix: - exclude: - - env: TRAVIS_EMPTY_JOB_WORKAROUND=true include: # Documentation - - env: CXX_COMPILER=g++-6 BUILD=Doc + - env: BUILD=Doc sudo: required - compiler: gcc # g++ 6 on Linux with C++14 - env: CXX_COMPILER=g++-6 BUILD=Debug STANDARD=14 compiler: gcc @@ -116,15 +113,9 @@ matrix: - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=0x compiler: gcc -install: - - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" - - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR} - - - cd ${TRAVIS_BUILD_DIR} - before_script: - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then export CXX=${CXX_COMPILER}; fi - - ${CXX} --version + - if [[ "${BUILD}" != "Doc" ]]; then ${CXX} --version; fi script: - support/travis-build.py diff --git a/include/fmt/core.h b/include/fmt/core.h index 17b685a23319..e8a6f6159a8e 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -36,6 +36,12 @@ # define FMT_HAS_CPP_ATTRIBUTE(x) 0 #endif +#if defined(__GNUC__) && !defined(__clang__) +# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#else +# define FMT_GCC_VERSION 0 +#endif + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) # define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION #else @@ -557,21 +563,22 @@ struct typed_value : value { template FMT_CONSTEXPR basic_format_arg make_arg(const T &value); -#if FMT_GCC_VERSION >= 406 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wuseless-cast" -#endif - #define FMT_MAKE_VALUE(TAG, ArgType, ValueType) \ template \ FMT_CONSTEXPR typed_value make_value(ArgType val) { \ return static_cast(val); \ } +#define FMT_MAKE_VALUE_SAME(TAG, Type) \ + template \ + FMT_CONSTEXPR typed_value make_value(Type val) { \ + return val; \ + } + FMT_MAKE_VALUE(bool_type, bool, int) FMT_MAKE_VALUE(int_type, short, int) FMT_MAKE_VALUE(uint_type, unsigned short, unsigned) -FMT_MAKE_VALUE(int_type, int, int) +FMT_MAKE_VALUE_SAME(int_type, int) FMT_MAKE_VALUE(uint_type, unsigned, unsigned) // To minimize the number of types we need to deal with, long is translated @@ -586,7 +593,7 @@ FMT_MAKE_VALUE( (sizeof(unsigned long) == sizeof(unsigned) ? uint_type : ulong_long_type), unsigned long, ulong_type) -FMT_MAKE_VALUE(long_long_type, long long, long long) +FMT_MAKE_VALUE_SAME(long_long_type, long long) FMT_MAKE_VALUE(ulong_long_type, unsigned long long, unsigned long long) FMT_MAKE_VALUE(int_type, signed char, int) FMT_MAKE_VALUE(uint_type, unsigned char, unsigned) @@ -601,8 +608,8 @@ inline typed_value make_value(wchar_t val) { #endif FMT_MAKE_VALUE(double_type, float, double) -FMT_MAKE_VALUE(double_type, double, double) -FMT_MAKE_VALUE(long_double_type, long double, long double) +FMT_MAKE_VALUE_SAME(double_type, double) +FMT_MAKE_VALUE_SAME(long_double_type, long double) // Formatting of wide strings into a narrow buffer and multibyte strings // into a wide buffer is disallowed (https://github.com/fmtlib/fmt/pull/606). @@ -612,28 +619,22 @@ FMT_MAKE_VALUE(cstring_type, const typename C::char_type*, const typename C::char_type*) FMT_MAKE_VALUE(cstring_type, signed char*, const signed char*) -FMT_MAKE_VALUE(cstring_type, const signed char*, const signed char*) +FMT_MAKE_VALUE_SAME(cstring_type, const signed char*) FMT_MAKE_VALUE(cstring_type, unsigned char*, const unsigned char*) -FMT_MAKE_VALUE(cstring_type, const unsigned char*, const unsigned char*) -FMT_MAKE_VALUE(string_type, basic_string_view, - basic_string_view) +FMT_MAKE_VALUE_SAME(cstring_type, const unsigned char*) +FMT_MAKE_VALUE_SAME(string_type, basic_string_view) FMT_MAKE_VALUE(string_type, typename basic_string_view::type, basic_string_view) FMT_MAKE_VALUE(string_type, const std::basic_string&, basic_string_view) FMT_MAKE_VALUE(pointer_type, void*, const void*) -FMT_MAKE_VALUE(pointer_type, const void*, const void*) +FMT_MAKE_VALUE_SAME(pointer_type, const void*) #if FMT_USE_NULLPTR FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void*) #endif -#if FMT_GCC_VERSION >= 406 -// -Wuseless-cast -# pragma GCC diagnostic pop -#endif - // Formatting of arbitrary pointers is disallowed. If you want to output a // pointer cast it to "void *" or "const void *". In particular, this forbids // formatting of "[const] volatile char *" which is printed as bool by diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index ac29038c68ea..2495b0f33055 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -65,8 +65,7 @@ inline fmt::internal::null<> strerror_s(char *, std::size_t, ...) { FMT_BEGIN_NAMESPACE -FMT_FUNC format_error::~format_error() throw() {} -FMT_FUNC system_error::~system_error() FMT_DTOR_NOEXCEPT {} +namespace { #ifndef _MSC_VER # define FMT_SNPRINTF snprintf diff --git a/include/fmt/format.h b/include/fmt/format.h index f7bfe233095f..75ca3a178daa 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -37,12 +37,6 @@ #include #include -#if defined(__GNUC__) && !defined(__clang__) -# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -#else -# define FMT_GCC_VERSION 0 -#endif - #ifdef __clang__ # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) #else @@ -63,7 +57,8 @@ # define FMT_MSC_VER 0 #endif -#if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION +#if (defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 406) || \ + FMT_CLANG_VERSION # pragma GCC diagnostic push // Disable the warning about declaration shadowing because it affects too @@ -81,8 +76,6 @@ # pragma clang diagnostic ignored "-Wweak-vtables" # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wgnu-statement-expression" -# pragma clang diagnostic ignored "-Wc++98-compat" -# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" # pragma clang diagnostic ignored "-Wglobal-constructors" # pragma clang diagnostic ignored "-Wdisabled-macro-expansion" # pragma clang diagnostic ignored "-Wdocumentation-unknown-command" @@ -3146,7 +3139,7 @@ struct formatter< break; case internal::char_type: handle_char_specs(specs_, internal::char_specs_checker( - type_spec, eh)); + static_cast(type_spec), eh)); break; case internal::double_type: case internal::long_double_type: @@ -3178,8 +3171,8 @@ struct formatter< internal::handle_dynamic_spec( specs_.precision_, specs_.precision_ref, ctx); typedef output_range range; - visit(arg_formatter(ctx, specs_), + typename FormatContext::char_type> range_type; + visit(arg_formatter(ctx, specs_), internal::make_arg(val)); return ctx.out(); } diff --git a/include/fmt/printf.h b/include/fmt/printf.h index 5a396964a2b3..bf4a293bbc59 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -52,7 +52,6 @@ class printf_precision_handler: public function { typename std::enable_if::value, int>::type operator()(T) { FMT_THROW(format_error("precision is not integer")); - return 0; } }; @@ -194,7 +193,6 @@ class printf_width_handler: public function { typename std::enable_if::value, unsigned>::type operator()(T) { FMT_THROW(format_error("width is not integer")); - return 0; } }; } // namespace internal diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 3e8480a1ac18..e5dc63f7e616 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -126,8 +126,38 @@ struct is_tuple_like { is_tuple_like_::value && !is_range_::value; }; -template -void for_each(std::index_sequence, Tuple &&tup, F &&f) noexcept { +// Check for integer_sequence +#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1910 +template +using integer_sequence = std::integer_sequence; +template +using index_sequence = std::index_sequence; +template +using make_index_sequence = std::make_index_sequence; +#else +template +struct integer_sequence { + typedef T value_type; + + static FMT_CONSTEXPR std::size_t size() { + return sizeof...(N); + } +}; + +template +using index_sequence = integer_sequence; + +template +struct make_integer_sequence : make_integer_sequence {}; +template +struct make_integer_sequence : integer_sequence {}; + +template +using make_index_sequence = make_integer_sequence; +#endif + +template +void for_each(index_sequence, Tuple &&tup, F &&f) noexcept { using std::get; // using free function get(T) now. const int _[] = {0, ((void)f(get(tup)), 0)...}; @@ -135,7 +165,7 @@ void for_each(std::index_sequence, Tuple &&tup, F &&f) noexcept { } template -FMT_CONSTEXPR std::make_index_sequence::value> +FMT_CONSTEXPR make_index_sequence::value> get_indexes(T const &) { return {}; } template diff --git a/include/fmt/time.h b/include/fmt/time.h index 5976ea6e14f1..7ca967f6b2cd 100644 --- a/include/fmt/time.h +++ b/include/fmt/time.h @@ -54,7 +54,6 @@ inline std::tm localtime(std::time_t time) { return lt.tm_; // Too big time values may be unsupported. FMT_THROW(format_error("time_t value out of range")); - return std::tm(); } // Thread-safe replacement for std::gmtime @@ -90,7 +89,6 @@ inline std::tm gmtime(std::time_t time) { return gt.tm_; // Too big time values may be unsupported. FMT_THROW(format_error("time_t value out of range")); - return std::tm(); } namespace internal { diff --git a/support/appveyor.yml b/support/appveyor.yml index cc5ef9a97a7c..ede92196077e 100644 --- a/support/appveyor.yml +++ b/support/appveyor.yml @@ -1,4 +1,6 @@ -configuration: Debug +configuration: + - Debug + - Release clone_depth: 1 @@ -32,7 +34,7 @@ before_build: - mkdir build - cd build - - ps: cmake -G "$($env:CMAKE_GENERATOR)$($env:CMAKE_GENERATOR_SUFFIX)" -DFMT_WERROR=OFF -DFMT_PEDANTIC=ON -DCMAKE_BUILD_TYPE=Debug .. + - ps: cmake -G "$($env:CMAKE_GENERATOR)$($env:CMAKE_GENERATOR_SUFFIX)" -DFMT_WERROR=OFF -DFMT_PEDANTIC=ON -DCMAKE_BUILD_TYPE="$($env:configuration)" .. build: project: C:\projects\fmt\build\fmt.sln @@ -42,7 +44,7 @@ build: test_script: - ps: | New-Item .\DartConfiguration.tcl -ItemType file - ctest -C Debug -T Test + ctest -C "$($env:configuration)" -T Test $XSLInputElement = New-Object System.Xml.Xsl.XslCompiledTransform $XslInputElement.Load("https://raw.githubusercontent.com/rpavlik/jenkins-ctest-plugin/master/ctest-to-junit.xsl") $file = $(ls Testing\*\Test.xml) | Select -first 1 diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc index 79ddd39657d2..d7511cd0f39e 100644 --- a/test/format-impl-test.cc +++ b/test/format-impl-test.cc @@ -30,9 +30,8 @@ struct ValueExtractor: fmt::internal::function { } template - T operator()(U) { + FMT_NORETURN T operator()(U) { throw std::runtime_error(fmt::format("invalid type {}", typeid(U).name())); - return T(); } }; diff --git a/test/gtest-extra-test.cc b/test/gtest-extra-test.cc index 53f0a0d6c882..2043f5499aae 100644 --- a/test/gtest-extra-test.cc +++ b/test/gtest-extra-test.cc @@ -195,39 +195,33 @@ TEST(ExpectSystemErrorTest, DoesNotGenerateUnreachableCodeWarning) { } TEST(AssertionSyntaxTest, ExceptionAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) { + if (::testing::internal::AlwaysFalse()) EXPECT_THROW_MSG(do_nothing(), std::exception, ""); - } - if (::testing::internal::AlwaysTrue()) { + if (::testing::internal::AlwaysTrue()) EXPECT_THROW_MSG(throw_exception(), std::exception, "test"); - } else { + else do_nothing(); - } } TEST(AssertionSyntaxTest, SystemErrorAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) { + if (::testing::internal::AlwaysFalse()) EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, ""); - } - if (::testing::internal::AlwaysTrue()) { + if (::testing::internal::AlwaysTrue()) EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test"); - } else { + else do_nothing(); - } } TEST(AssertionSyntaxTest, WriteAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) { + if (::testing::internal::AlwaysFalse()) EXPECT_WRITE(stdout, std::printf("x"), "x"); - } - if (::testing::internal::AlwaysTrue()) { + if (::testing::internal::AlwaysTrue()) EXPECT_WRITE(stdout, std::printf("x"), "x"); - } else { + else do_nothing(); - } } // Tests EXPECT_THROW_MSG. diff --git a/test/util-test.cc b/test/util-test.cc index a9329a384985..b22aa0edadb5 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -822,7 +822,8 @@ TEST(UtilTest, FormatLongWindowsError) { const int provisioning_not_allowed = 0x80284013L /*TBS_E_PROVISIONING_NOT_ALLOWED*/; if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, - provisioning_not_allowed, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + static_cast(provisioning_not_allowed), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&message), 0, 0) == 0) { return; } From ed839c4a9b583e80b66e10ca4bd10202be86eb90 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Tue, 15 May 2018 10:21:08 +0300 Subject: [PATCH 07/15] Reintroduce appveyor-build.py --- .travis.yml | 24 +++++++++++----- include/fmt/ostream.h | 8 ++++++ include/fmt/printf.h | 9 ++++++ support/appveyor-build.py | 47 ++++++++++++++++++++++++++++++++ support/appveyor-test-upload.ps1 | 11 ++++++++ support/appveyor.yml | 43 +++++++---------------------- 6 files changed, 102 insertions(+), 40 deletions(-) create mode 100644 support/appveyor-build.py create mode 100644 support/appveyor-test-upload.ps1 diff --git a/.travis.yml b/.travis.yml index 3d01de231ccd..85dd3d7e6e33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ os: linux git: depth: 1 -addons: - apt: - update: true - sources: &apt_sources - - ubuntu-toolchain-r-test - packages: - - g++-6 env: global: @@ -30,8 +23,22 @@ matrix: # g++ 6 on Linux with C++14 - env: CXX_COMPILER=g++-6 BUILD=Debug STANDARD=14 compiler: gcc + addons: + apt: + update: true + sources: + - ubuntu-toolchain-r-test + packages: + - g++-6 - env: CXX_COMPILER=g++-6 BUILD=Release STANDARD=14 compiler: gcc + addons: + apt: + update: true + sources: + - ubuntu-toolchain-r-test + packages: + - g++-6 # Apple clang on OS X with C++14 - env: BUILD=Debug STANDARD=14 compiler: clang @@ -79,6 +86,9 @@ matrix: # Android - language: android android: + addons: + apt: + update: true components: - tools - platform-tools diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index fdbe16983fb7..a836d16c1d15 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -140,13 +140,21 @@ inline void vprint(std::basic_ostream &os, template inline void print(std::ostream &os, string_view format_str, const Args & ... args) { +#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 440 + vprint(os, format_str, make_format_args(args...)); +#else vprint(os, format_str, make_format_args(args...)); +#endif } template inline void print(std::wostream &os, wstring_view format_str, const Args & ... args) { +#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 440 + vprint(os, format_str, make_format_args(args...)); +#else vprint(os, format_str, make_format_args(args...)); +#endif } FMT_END_NAMESPACE diff --git a/include/fmt/printf.h b/include/fmt/printf.h index bf4a293bbc59..29aef5036d9b 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -625,14 +625,23 @@ template inline int fprintf(std::FILE *f, string_view format_str, const Args & ... args) { auto vargs = make_format_args< typename printf_context::type>(args...); +#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 440 + return vfprintf(f, format_str, vargs); +#else return vfprintf(f, format_str, vargs); +#endif } template inline int fprintf(std::FILE *f, wstring_view format_str, const Args & ... args) { +#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 440 + return vfprintf(f, format_str, + make_format_args::type>(args...)); +#else return vfprintf(f, format_str, make_format_args::type>(args...)); +#endif } inline int vprintf(string_view format, printf_args args) { diff --git a/support/appveyor-build.py b/support/appveyor-build.py new file mode 100644 index 000000000000..d7b61562f49e --- /dev/null +++ b/support/appveyor-build.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# Build the project on AppVeyor. + +import os +from subprocess import check_call + +build = os.environ['BUILD'] +config = os.environ['CONFIGURATION'] +platform = os.environ['PLATFORM'] +path = os.environ['PATH'] +image = os.environ['APPVEYOR_BUILD_WORKER_IMAGE'] +jobid = os.environ['APPVEYOR_JOB_ID'] +cmake_command = ['cmake', '-DFMT_PEDANTIC=ON', '-DCMAKE_BUILD_TYPE=' + config, '..'] +if build == 'mingw': + cmake_command.append('-GMinGW Makefiles') + build_command = ['mingw32-make', '-j4'] + test_command = ['mingw32-make', 'test'] + # Remove the path to Git bin directory from $PATH because it breaks + # MinGW config. + path = path.replace(r'C:\Program Files (x86)\Git\bin', '') + os.environ['PATH'] = r'C:\MinGW\bin;' + path +else: + # Add MSBuild 14.0 to PATH as described in + # http://help.appveyor.com/discussions/problems/2229-v140-not-found-on-vs2105rc. + os.environ['PATH'] = r'C:\Program Files (x86)\MSBuild\15.0\Bin;' + path + if image == 'Visual Studio 2013': + generator = 'Visual Studio 12 2013' + elif image == 'Visual Studio 2015': + generator = 'Visual Studio 14 2015' + elif image == 'Visual Studio 2017': + generator = 'Visual Studio 15 2017' + if platform == 'x64': + generator += ' Win64' + cmake_command.append('-G' + generator) + # build_command = ['msbuild', r'C:\projects\fmt\build\fmt.sln', '/m:4', + # r'/logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"'] + build_command = ['cmake', '--build', '.', '--config', config, '--', '/m:4'] + test_command = ['ctest', '-C', config, '-T', 'Test'] + with open('DartConfiguration.tcl', 'w+') as file: + pass + +check_call(cmake_command) +check_call(build_command) +check_call(test_command) + +# Upload test results +# check_call([r'../support/appveyor-test-upload.ps1', '-configuration', config, '-jobid', jobid]) diff --git a/support/appveyor-test-upload.ps1 b/support/appveyor-test-upload.ps1 new file mode 100644 index 000000000000..0a2eb7afb8c1 --- /dev/null +++ b/support/appveyor-test-upload.ps1 @@ -0,0 +1,11 @@ +param ( + [Parameter(Mandatory=$true)][string]$configuration, + [Parameter(Mandatory=$true)][string]$jobid +) + +$XSLInputElement = New-Object System.Xml.Xsl.XslCompiledTransform +$XslInputElement.Load("https://raw.githubusercontent.com/rpavlik/jenkins-ctest-plugin/master/ctest-to-junit.xsl") +$file = $(ls Testing\*\Test.xml) | Select -first 1 +$XSLInputElement.Transform((Resolve-Path $file), (Join-Path (Resolve-Path .) "ctest-to-junit-results.xml")) +$wc = New-Object 'System.Net.WebClient' +$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$jobid", (Resolve-Path .\ctest-to-junit-results.xml)) diff --git a/support/appveyor.yml b/support/appveyor.yml index ede92196077e..a28305881487 100644 --- a/support/appveyor.yml +++ b/support/appveyor.yml @@ -8,49 +8,26 @@ platform: - Win32 - x64 +image: + - Visual Studio 2013 + - Visual Studio 2015 + - Visual Studio 2017 + environment: CTEST_OUTPUT_ON_FAILURE: 1 MSVC_DEFAULT_OPTIONS: ON - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - CMAKE_GENERATOR: Visual Studio 12 2013 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - CMAKE_GENERATOR: Visual Studio 14 2015 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - CMAKE_GENERATOR: Visual Studio 15 2017 + BUILD: msvc matrix: allow_failures: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - CMAKE_GENERATOR: Visual Studio 12 2013 - -init: - - ps: | - If ($env:Platform -Match "x64") { - $env:CMAKE_GENERATOR_SUFFIX=" Win64" - } + - image: Visual Studio 2013 before_build: - mkdir build - cd build - - - ps: cmake -G "$($env:CMAKE_GENERATOR)$($env:CMAKE_GENERATOR_SUFFIX)" -DFMT_WERROR=OFF -DFMT_PEDANTIC=ON -DCMAKE_BUILD_TYPE="$($env:configuration)" .. - -build: - project: C:\projects\fmt\build\fmt.sln - parallel: true - verbosity: normal - -test_script: - - ps: | - New-Item .\DartConfiguration.tcl -ItemType file - ctest -C "$($env:configuration)" -T Test - $XSLInputElement = New-Object System.Xml.Xsl.XslCompiledTransform - $XslInputElement.Load("https://raw.githubusercontent.com/rpavlik/jenkins-ctest-plugin/master/ctest-to-junit.xsl") - $file = $(ls Testing\*\Test.xml) | Select -first 1 - $XSLInputElement.Transform((Resolve-Path $file), (Join-Path (Resolve-Path .) "ctest-to-junit-results.xml")) - $wc = New-Object 'System.Net.WebClient' - $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\ctest-to-junit-results.xml)) + +build_script: + - python ../support/appveyor-build.py on_failure: - appveyor PushArtifact Testing/Temporary/LastTest.log From a8976bd3e9625b5008f27d8884f7144dd26680e2 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Thu, 17 May 2018 08:30:27 +0300 Subject: [PATCH 08/15] Remove ranges-test from tests --- include/fmt/ostream.h | 1 + include/fmt/printf.h | 1 + test/CMakeLists.txt | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index a836d16c1d15..32e9a9c193fb 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -141,6 +141,7 @@ template inline void print(std::ostream &os, string_view format_str, const Args & ... args) { #if FMT_GCC_VERSION && FMT_GCC_VERSION <= 440 + // Fix gcc's bugged template deduction vprint(os, format_str, make_format_args(args...)); #else vprint(os, format_str, make_format_args(args...)); diff --git a/include/fmt/printf.h b/include/fmt/printf.h index 29aef5036d9b..db1a0d738cba 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -626,6 +626,7 @@ inline int fprintf(std::FILE *f, string_view format_str, const Args & ... args) auto vargs = make_format_args< typename printf_context::type>(args...); #if FMT_GCC_VERSION && FMT_GCC_VERSION <= 440 + // Fix gcc's bugged template deduction return vfprintf(f, format_str, vargs); #else return vfprintf(f, format_str, vargs); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 07b10a0a0b75..785bb6943f9f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -92,7 +92,7 @@ add_fmt_test(printf-test) add_fmt_test(time-test) add_fmt_test(util-test mock-allocator.h) add_fmt_test(custom-formatter-test) -add_fmt_test(ranges-test) +#add_fmt_test(ranges-test) # Enable stricter options for one test to make sure that the header is free of # warnings. @@ -148,7 +148,7 @@ if (FMT_PEDANTIC) "${CMAKE_CURRENT_BINARY_DIR}/compile-test" --build-generator ${CMAKE_GENERATOR} --build-makeprogram ${CMAKE_MAKE_PROGRAM} - --build-options + --build-options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" "-DCPP14_FLAG=${CPP14_FLAG}" "-DSUPPORTS_USER_DEFINED_LITERALS=${SUPPORTS_USER_DEFINED_LITERALS}") From 584a99c934701ea07d0035009d8e6c372b5e17b8 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Tue, 22 May 2018 09:10:01 +0300 Subject: [PATCH 09/15] Remove (some) explicit warning suppressions Fix C++ standard setting in CI --- .travis.yml | 2 +- CMakeLists.txt | 14 ++++++++++++-- include/fmt/core.h | 4 ++-- include/fmt/format-inl.h | 25 ------------------------- include/fmt/format.h | 25 ++----------------------- support/travis-build.py | 4 ++-- 6 files changed, 19 insertions(+), 55 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85dd3d7e6e33..522c05b87973 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,7 +120,7 @@ matrix: # Errors - env: CXX_COMPILER=g++-4.8 BUILD=Debug STANDARD=11 compiler: gcc - - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=0x + - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=11 compiler: gcc before_script: diff --git a/CMakeLists.txt b/CMakeLists.txt index 23de596908be..92fbf2b57215 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,14 @@ option(FMT_INSTALL "Generate the install target." ${MASTER_PROJECT}) option(FMT_TEST "Generate the test target." ${MASTER_PROJECT}) option(FMT_USE_CPP14 "Enable the addition of C++14 compiler flags." ON) +if (NOT CMAKE_CXX_STANDARD) + if (FMT_USE_CPP14) + set(CMAKE_CXX_STANDARD 14) + else () + set(CMAKE_CXX_STANDARD 11) + endif() +endif() + project(FMT) # Get version from core.h @@ -67,7 +75,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") -Wcast-align -Wnon-virtual-dtor -Wctor-dtor-privacy -Wdisabled-optimization -Winvalid-pch -Wmissing-declarations -Woverloaded-virtual - -Wno-sign-conversion -Wno-shadow) + -Wno-sign-conversion -Wno-shadow -Wno-format-nonliteral + -Wno-dangling-else) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept) endif () @@ -90,7 +99,8 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-reserved-id-macro -Wno-global-constructors -Wno-disabled-macro-expansion -Wno-switch-enum -Wno-documentation-unknown-command - -Wno-gnu-string-literal-operator-template) + -Wno-gnu-string-literal-operator-template -Wno-unused-member-function + -Wno-format-nonliteral -Wno-missing-noreturn -Wno-undefined-func-template) set(WERROR_FLAG -Werror) endif () diff --git a/include/fmt/core.h b/include/fmt/core.h index 7941ece03c22..50bf6b008256 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -566,7 +566,7 @@ FMT_MAKE_VALUE(bool_type, bool, int) FMT_MAKE_VALUE(int_type, short, int) FMT_MAKE_VALUE(uint_type, unsigned short, unsigned) FMT_MAKE_VALUE_SAME(int_type, int) -FMT_MAKE_VALUE(uint_type, unsigned, unsigned) +FMT_MAKE_VALUE_SAME(uint_type, unsigned) // To minimize the number of types we need to deal with, long is translated // either to int or to long long depending on its size. @@ -581,7 +581,7 @@ FMT_MAKE_VALUE( unsigned long, ulong_type) FMT_MAKE_VALUE_SAME(long_long_type, long long) -FMT_MAKE_VALUE(ulong_long_type, unsigned long long, unsigned long long) +FMT_MAKE_VALUE_SAME(ulong_long_type, unsigned long long) FMT_MAKE_VALUE(int_type, signed char, int) FMT_MAKE_VALUE(uint_type, unsigned char, unsigned) FMT_MAKE_VALUE(char_type, char, int) diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 2495b0f33055..e9b495cbd4b3 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -113,11 +113,6 @@ int safe_strerror( // A noop assignment operator to avoid bogus warnings. void operator=(const StrError &) {} -#if FMT_CLANG_VERSION -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wunused-member-function" -#endif - // Handle the result of XSI-compliant version of strerror_r. int handle(int result) { // glibc versions before 2.13 return result in errno. @@ -152,10 +147,6 @@ int safe_strerror( return errno; } -#if FMT_CLANG_VERSION -# pragma clang diagnostic pop -#endif - public: StrError(int err_code, char *&buf, std::size_t buf_size) : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} @@ -221,11 +212,6 @@ FMT_FUNC void system_error::init( } namespace internal { -#if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wformat-nonliteral" -#endif - template int char_traits::format_float( char *buffer, std::size_t size, const char *format, @@ -254,10 +240,6 @@ int char_traits::format_float( FMT_SWPRINTF(buffer, size, format, width, precision, value); } -#if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION -# pragma GCC diagnostic pop -#endif - template const char basic_data::DIGITS[] = "0001020304050607080910111213141516171819" @@ -477,16 +459,9 @@ void basic_fixed_buffer::grow(std::size_t) { FMT_THROW(std::runtime_error("buffer overflow")); } -#if FMT_CLANG_VERSION -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmissing-noreturn" -#endif FMT_FUNC void internal::error_handler::on_error(const char *message) { FMT_THROW(format_error(message)); } -#if FMT_CLANG_VERSION -# pragma clang diagnostic pop -#endif FMT_FUNC void report_system_error( int error_code, fmt::string_view message) FMT_NOEXCEPT { diff --git a/include/fmt/format.h b/include/fmt/format.h index a058e51387f8..fcbfcc71050f 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -70,18 +70,6 @@ # pragma GCC diagnostic ignored "-Wsign-conversion" #endif -#if FMT_CLANG_VERSION && !FMT_ICC_VERSION -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wswitch-enum" -# pragma clang diagnostic ignored "-Wweak-vtables" -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wgnu-statement-expression" -# pragma clang diagnostic ignored "-Wglobal-constructors" -# pragma clang diagnostic ignored "-Wdisabled-macro-expansion" -# pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -# pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template" -#endif - #include "core.h" #ifdef _SECURE_SCL @@ -1617,6 +1605,8 @@ FMT_CONSTEXPR unsigned parse_nonnegative_int(Iterator &it, ErrorHandler &&eh) { } #if FMT_MSC_VER +// Warns that the compiler cannot generate an assignment operator +// The class has a reference member variable, so this is obviously the case # pragma warning(push) # pragma warning(disable: 4512) #endif @@ -2563,18 +2553,11 @@ class basic_writer { }; void on_num() { - #if FMT_CLANG_VERSION - # pragma clang diagnostic push - # pragma clang diagnostic ignored "-Wundefined-func-template" - #endif unsigned num_digits = internal::count_digits(abs_value); char_type sep = internal::thousands_sep(writer.locale_.get()); unsigned size = num_digits + SEP_SIZE * ((num_digits - 1) / 3); writer.write_int(size, get_prefix(), spec, num_writer{abs_value, size, sep}); - #if FMT_CLANG_VERSION - # pragma clang diagnostic pop - #endif } void on_error() { @@ -3693,8 +3676,4 @@ FMT_END_NAMESPACE # pragma GCC diagnostic pop #endif -#if FMT_CLANG_VERSION && !defined(FMT_ICC_VERSION) -# pragma clang diagnostic pop -#endif - #endif // FMT_FORMAT_H_ diff --git a/support/travis-build.py b/support/travis-build.py index 21fc08712438..6cdbf1b8e229 100755 --- a/support/travis-build.py +++ b/support/travis-build.py @@ -90,7 +90,7 @@ def install_dependencies(): ] extra_cmake_flags = [] if standard != '14': - extra_cmake_flags = ['-DCMAKE_CXX_FLAGS=-std=c++' + standard] + extra_cmake_flags = ['-DCMAKE_CXX_STANDARD=' + standard] check_call(['cmake', '-DFMT_DOC=OFF', '-DFMT_PEDANTIC=ON', '-DFMT_WERROR=ON', fmt_dir] + common_cmake_flags + extra_cmake_flags, cwd=build_dir) @@ -110,7 +110,7 @@ def install_dependencies(): # Test installation. makedirs_if_not_exist(test_build_dir) -check_call(['cmake', '-DCMAKE_CXX_FLAGS=-std=c++' + standard, +check_call(['cmake', '-DCMAKE_CXX_STANDARD=' + standard, os.path.join(fmt_dir, "test", "find-package-test")] + common_cmake_flags, cwd=test_build_dir) check_call(['make', '-j4'], cwd=test_build_dir) From 8d270366e7bc335fbf486bc5316989b6aff24304 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Tue, 22 May 2018 09:10:01 +0300 Subject: [PATCH 10/15] Remove (some) explicit warning suppressions Fix C++ standard setting in CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 522c05b87973..1cdb9f5e59f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,7 +74,7 @@ matrix: - env: CXX_COMPILER=g++-4.8 BUILD=Debug STANDARD=11 compiler: gcc # g++ 4.4 on Linux with C++11 - - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=0x + - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=11 compiler: gcc addons: apt: From 16533b275b280e9cb51748688eef6f9f808f4291 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Wed, 23 May 2018 14:12:13 +0300 Subject: [PATCH 11/15] Fix test builds with C++11 --- include/fmt/format.h | 2 +- test/CMakeLists.txt | 15 +++------------ test/add-subdirectory-test/CMakeLists.txt | 2 -- test/compile-test/CMakeLists.txt | 1 - test/find-package-test/CMakeLists.txt | 2 -- 5 files changed, 4 insertions(+), 18 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 07c166944390..ccafe4975157 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3645,7 +3645,7 @@ FMT_END_NAMESPACE #define FMT_STRING(s) [] { \ struct S : fmt::format_string { \ - static FMT_CONSTEXPR auto data() { return s; } \ + static FMT_CONSTEXPR decltype(s) data() { return s; } \ static FMT_CONSTEXPR size_t size() { return sizeof(s); } \ }; \ return S{}; \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 785bb6943f9f..8978a083f042 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,7 +7,6 @@ # at http://code.google.com/p/googletest/wiki/FAQ for more details. add_library(gmock STATIC gmock-gtest-all.cc gmock/gmock.h gtest/gtest.h gtest/gtest-spi.h) -target_compile_options(gmock PUBLIC ${CPP14_FLAG}) target_compile_definitions(gmock PUBLIC GTEST_HAS_STD_WSTRING=1) target_include_directories(gmock PUBLIC .) @@ -94,12 +93,6 @@ add_fmt_test(util-test mock-allocator.h) add_fmt_test(custom-formatter-test) #add_fmt_test(ranges-test) -# Enable stricter options for one test to make sure that the header is free of -# warnings. -if (FMT_PEDANTIC AND MSVC) - target_compile_options(format-test PRIVATE /W4) -endif () - if (HAVE_OPEN) add_fmt_executable(posix-mock-test posix-mock-test.cc ../src/format.cc ${TEST_MAIN_SRC}) @@ -126,7 +119,6 @@ endif () check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG) if (HAVE_FNO_EXCEPTIONS_FLAG) add_library(noexception-test ../src/format.cc) - target_compile_options(noexception-test PUBLIC ${CPP14_FLAG}) target_include_directories( noexception-test PRIVATE ${PROJECT_SOURCE_DIR}/include) target_compile_options(noexception-test PRIVATE -fno-exceptions) @@ -136,7 +128,6 @@ if (FMT_PEDANTIC) # Test that the library compiles without windows.h. if (CMAKE_SYSTEM_NAME STREQUAL "Windows") add_library(no-windows-h-test ../src/format.cc) - target_compile_options(no-windows-h-test PUBLIC ${CPP14_FLAG}) target_include_directories( no-windows-h-test PRIVATE ${PROJECT_SOURCE_DIR}/include) target_compile_definitions(no-windows-h-test PRIVATE FMT_USE_WINDOWS_H=0) @@ -150,7 +141,7 @@ if (FMT_PEDANTIC) --build-makeprogram ${CMAKE_MAKE_PROGRAM} --build-options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" - "-DCPP14_FLAG=${CPP14_FLAG}" + "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" "-DSUPPORTS_USER_DEFINED_LITERALS=${SUPPORTS_USER_DEFINED_LITERALS}") # test if the targets are findable from the build directory @@ -163,7 +154,7 @@ if (FMT_PEDANTIC) --build-makeprogram ${CMAKE_MAKE_PROGRAM} --build-options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" - "-DCPP14_FLAG=${CPP14_FLAG}" + "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" "-DFMT_DIR=${PROJECT_BINARY_DIR}" "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") @@ -177,6 +168,6 @@ if (FMT_PEDANTIC) --build-makeprogram ${CMAKE_MAKE_PROGRAM} --build-options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" - "-DCPP14_FLAG=${CPP14_FLAG}" + "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") endif () diff --git a/test/add-subdirectory-test/CMakeLists.txt b/test/add-subdirectory-test/CMakeLists.txt index 4a4441c5b57a..d1edd8a52796 100644 --- a/test/add-subdirectory-test/CMakeLists.txt +++ b/test/add-subdirectory-test/CMakeLists.txt @@ -5,11 +5,9 @@ project(fmt-test) add_subdirectory(../.. fmt) add_executable(library-test "main.cc") -target_compile_options(library-test PUBLIC ${CPP14_FLAG}) target_link_libraries(library-test fmt::fmt) if (TARGET fmt::fmt-header-only) add_executable(header-only-test "main.cc") - target_compile_options(header-only-test PUBLIC ${CPP14_FLAG}) target_link_libraries(header-only-test fmt::fmt-header-only) endif () diff --git a/test/compile-test/CMakeLists.txt b/test/compile-test/CMakeLists.txt index dda1fb96468e..dbf52b07657d 100644 --- a/test/compile-test/CMakeLists.txt +++ b/test/compile-test/CMakeLists.txt @@ -4,7 +4,6 @@ cmake_minimum_required(VERSION 2.8) include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../../include) -set(CMAKE_REQUIRED_FLAGS ${CPP14_FLAG}) function (generate_source result fragment) set(${result} " diff --git a/test/find-package-test/CMakeLists.txt b/test/find-package-test/CMakeLists.txt index e860879c6cd3..40c075609602 100644 --- a/test/find-package-test/CMakeLists.txt +++ b/test/find-package-test/CMakeLists.txt @@ -5,11 +5,9 @@ project(fmt-test) find_package(FMT REQUIRED) add_executable(library-test main.cc) -target_compile_options(library-test PUBLIC ${CPP14_FLAG}) target_link_libraries(library-test fmt::fmt) if (TARGET fmt::fmt-header-only) add_executable(header-only-test main.cc) - target_compile_options(header-only-test PUBLIC ${CPP14_FLAG}) target_link_libraries(header-only-test fmt::fmt-header-only) endif () From 6ba5f70f998735d9ac4ffe834f83f028b98f8a16 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Sat, 26 May 2018 22:04:06 +0300 Subject: [PATCH 12/15] Enable pedantic warnings on tests --- .ropeproject/config.py | 103 ++++++++++++++++++++ .ropeproject/globalnames | Bin 0 -> 1713 bytes .ropeproject/history | Bin 0 -> 14 bytes .ropeproject/objectdb | Bin 0 -> 379 bytes CMakeLists.txt | 54 +++++------ include/fmt/core.h | 6 ++ include/fmt/format.h | 8 +- include/fmt/ranges.h | 8 +- support/cmake/cxx14.cmake | 112 +++++++++++----------- support/travis-build.py | 21 ++-- test/CMakeLists.txt | 27 +++++- test/add-subdirectory-test/CMakeLists.txt | 6 +- test/assert-test.cc | 2 +- test/compile-test/CMakeLists.txt | 5 +- test/custom-formatter-test.cc | 12 ++- test/find-package-test/CMakeLists.txt | 6 +- test/format-impl-test.cc | 6 +- test/format-test.cc | 31 +++--- test/gmock-gtest-all.cc | 2 +- test/gmock/gmock.h | 2 +- test/gtest-extra-test.cc | 8 +- test/gtest-extra.cc | 2 +- test/gtest-extra.h | 4 +- test/mock-allocator.h | 6 +- test/ostream-test.cc | 16 ++-- test/posix-mock-test.cc | 25 ++--- test/posix-test.cc | 34 +++---- test/printf-test.cc | 18 ++-- test/ranges-test.cc | 2 +- test/test-main.cc | 2 +- test/time-test.cc | 10 +- test/util-test.cc | 48 +++++----- test/util.h | 2 +- 33 files changed, 369 insertions(+), 219 deletions(-) create mode 100644 .ropeproject/config.py create mode 100644 .ropeproject/globalnames create mode 100644 .ropeproject/history create mode 100644 .ropeproject/objectdb diff --git a/.ropeproject/config.py b/.ropeproject/config.py new file mode 100644 index 000000000000..45e1fb46ca5c --- /dev/null +++ b/.ropeproject/config.py @@ -0,0 +1,103 @@ +# The default ``config.py`` +# flake8: noqa + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs['ignored_resources'] = [ + '*.pyc', '*~', '.ropeproject', '.hg', '.svn', '_svn', + '.git', '.tox', '.env', 'env', 'venv', 'node_modules', + 'bower_components' + ] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + #prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + #prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + #prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs['save_objectdb'] = True + prefs['compress_objectdb'] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs['automatic_soa'] = True + # The depth of calls to follow in static object analysis + prefs['soa_followed_calls'] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs['perform_doa'] = True + + # Rope can check the validity of its object DB when running. + prefs['validate_objectdb'] = True + + # How many undos to hold? + prefs['max_history_items'] = 32 + + # Shows whether to save history across sessions. + prefs['save_history'] = True + prefs['compress_history'] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs['indent_size'] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs['extension_modules'] = [] + + # Add all standard c-extensions to extension_modules list. + prefs['import_dynload_stdmods'] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs['ignore_syntax_errors'] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs['ignore_bad_imports'] = False + + # If `True`, rope will insert new module imports as + # `from import ` by default. + prefs['prefer_module_from_imports'] = False + + # If `True`, rope will transform a comma list of imports into + # multiple separate import statements when organizing + # imports. + prefs['split_imports'] = False + + # If `True`, rope will sort imports alphabetically by module name + # instead of alphabetically by import statement, with from imports + # after normal imports. + prefs['sort_imports_alphabetically'] = False + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! diff --git a/.ropeproject/globalnames b/.ropeproject/globalnames new file mode 100644 index 0000000000000000000000000000000000000000..e4e1c7fb787349708ddb0aa854a5dd73c28e276e GIT binary patch literal 1713 zcmYjRX?NT-6iw58FLYsF%VMA@Z7KUw+9tF>LP{E_SO%l9pFK)!Nl%i~3FmMQKb`06 zNiv^oz4hMvp7h`1zr2vCV+#ulr7N6Id}zdrnYt*3Wf)eqtvg-QN(e6SVRdTXvobY_ zkEr8fc%)OJVEL#zDW?>)jg<>6A5*90yh^&-i#V>%isha}6q7yM33WnjcSGH^WD}o6 z$@{KtwJrG+z^(gaoaNJq+#v2uppwtvIQVqKXVrPBGaTdNi3_Rd5}yO6bxZ4E%?0A~ zD7a$MgaTi{Vbg7sjrH}X!%UK>V zUzrQg$+i64ydl&({Jc81->IZZca8LVVXjxC0t&ncNWHka$-5|n;g`UHrXqXfm(>v| zv}}sRufRSV>#GDu;cUgPjrjEp2wELwZn?zp8!${#+vK85OZ+C(JTT-!cfwZ*RYOd- z+LGTI@!J_tnwZxjX*bRTRs0T$ZT5T62;so*Vp40%PlAz#oMFTQW`{!J_efn4(48-J zqNT!#(WKp_F_whiAMpp7IxGPXWZ$mguQY*|@Fz|AIv}|&c^UVI13=lGUYi>uzL`y~ zLEWMuZS!J6#kR!qEo5zU)(W7H)CFl!1QG=KxHCfH5r3Nje`r%6%1xEi)I`~!yXvyEZ1pyYVzGBvmj)-_ zQy?+}$(CdbLy_-;LnTCep_d`l(2`dG8e7r(z5~Br4t{_nnFoY<2;@na(@^Dm zjH{5P`9U3$#-4vfDWPgh9ZFsW|9w1Cd=1xV#$L`pVT_4lnvJMOu#U8%=a^TG7NH-Z zQ$N0+(W&AMLZGpWUo7vn19XX$<)$U?p31)P z-y_x;>a@nnJiW91%Q+rQdU{|gP)csO=Mp;-O>IqO3Q=7a_8(%xq@+gfswz_AN-fHK zD$g|pnYEliOT%VRcj|cy?m$rR`d4nDNx=5Wo+#X3= Z%n)7Ti?=FvP83V2oj-PvGDLzUd2O81iGhyi z@}2KLU!xWQUj{)C*S3laCE~JixzVp|9UIHa21hMMD?alp8(C4}i1eqbjK;C7Oi4^6 zmY7j&OIuSlsR%!$Z@=rzggA-5F>Y}h@u}yPwl2|G zoOigeEiOCE#P2Y((xfDDl@G>wi$%2BIYg}rr!=nl*c)A47KEGpfbo_uhHv*rS!PKO e=W*BL{t)}{m-Vp*cG=_6;mOB-?(iaN%YFbYxO0jC literal 0 HcmV?d00001 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ac29fa02d59..0dc4e4695d4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ message(STATUS "CMake version: ${CMAKE_VERSION}") -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.1.0) # Determine if fmt is built as a subproject (using add_subdirectory) # or if it is the master project. @@ -28,20 +28,12 @@ if (NOT CMAKE_BUILD_TYPE) endif () option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF) +option(FMT_WERROR "Halt the compilation with an error on compiler warnings." OFF) # Options that control generation of various targets. option(FMT_DOC "Generate the doc target." ${MASTER_PROJECT}) option(FMT_INSTALL "Generate the install target." ${MASTER_PROJECT}) option(FMT_TEST "Generate the test target." ${MASTER_PROJECT}) -option(FMT_USE_CPP14 "Enable the addition of C++14 compiler flags." ON) - -if (NOT CMAKE_CXX_STANDARD) - if (FMT_USE_CPP14) - set(CMAKE_CXX_STANDARD 14) - else () - set(CMAKE_CXX_STANDARD 11) - endif() -endif() project(FMT) @@ -66,6 +58,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/support/cmake") include(cxx14) +include(CheckCXXCompilerFlag) if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(PEDANTIC_COMPILE_FLAGS -pedantic-errors -Wall -Wextra -pedantic @@ -76,16 +69,16 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") -Wctor-dtor-privacy -Wdisabled-optimization -Winvalid-pch -Wmissing-declarations -Woverloaded-virtual -Wno-sign-conversion -Wno-shadow -Wno-format-nonliteral - -Wno-dangling-else) - if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) + -Wno-dangling-else -Wno-ctor-dtor-privacy) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept) endif () - if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wdouble-promotion -Wtrampolines -Wzero-as-null-pointer-constant -Wuseless-cast -Wvector-operation-performance -Wsized-deallocation) endif () - if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2 -Wnull-dereference -Wduplicated-cond) endif () @@ -100,9 +93,22 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") -Wno-global-constructors -Wno-disabled-macro-expansion -Wno-switch-enum -Wno-documentation-unknown-command -Wno-gnu-string-literal-operator-template -Wno-unused-member-function - -Wno-format-nonliteral -Wno-missing-noreturn -Wno-undefined-func-template) + -Wno-format-nonliteral -Wno-missing-noreturn -Wno-undefined-func-template + -Wno-shadow -Wno-sign-conversion -Wno-used-but-marked-unused + -Wno-covered-switch-default -Wno-missing-variable-declarations + -Wno-double-promotion) set(WERROR_FLAG -Werror) + + check_cxx_compiler_flag(-Wno-zero-as-null-pointer-constant HAS_NULLPTR_WARNING) + if (HAS_NULLPTR_WARNING) + set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wno-zero-as-null-pointer-constant) + endif () + + check_cxx_compiler_flag(-Wno-gnu-string-literal-operator-template HAS_GNU_UDL_WARNING) + if (HAS_GNU_UDL_WARNING) + set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wno-gnu-string-literal-operator-template) + endif () endif () if (MSVC) @@ -153,9 +159,6 @@ endif () add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} README.rst ChangeLog.rst) add_library(fmt::fmt ALIAS fmt) -# Starting with CMake 3.1 the CXX_STANDARD property can be used instead. -# Don't export -std since it may break projects that use other standards. -target_compile_options(fmt PRIVATE ${CPP14_FLAG}) if (FMT_WERROR) target_compile_options(fmt PRIVATE ${WERROR_FLAG}) endif () @@ -180,17 +183,14 @@ if (BUILD_SHARED_LIBS) target_compile_definitions(fmt PRIVATE FMT_EXPORT INTERFACE FMT_SHARED) endif () -# Additionally define a header-only library when CMake is new enough. -if (CMAKE_VERSION VERSION_GREATER 3.1.0 OR CMAKE_VERSION VERSION_EQUAL 3.1.0) - add_library(fmt-header-only INTERFACE) - add_library(fmt::fmt-header-only ALIAS fmt-header-only) +add_library(fmt-header-only INTERFACE) +add_library(fmt::fmt-header-only ALIAS fmt-header-only) - target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1) +target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1) - target_include_directories(fmt-header-only INTERFACE - $ - $) -endif () +target_include_directories(fmt-header-only INTERFACE + $ + $) # Install targets. if (FMT_INSTALL) diff --git a/include/fmt/core.h b/include/fmt/core.h index 55fddfbdcfba..9bd3db13e44d 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -48,6 +48,12 @@ # define FMT_HAS_GXX_CXX11 0 #endif +#ifdef _MSC_VER +# define FMT_MSC_VER _MSC_VER +#else +# define FMT_MSC_VER 0 +#endif + // Check if relaxed c++14 constexpr is supported. // GCC doesn't allow throw in constexpr until version 6 (bug 67371). #ifndef FMT_USE_CONSTEXPR diff --git a/include/fmt/format.h b/include/fmt/format.h index ccafe4975157..410c19bef996 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -51,12 +51,6 @@ # define FMT_ICC_VERSION 0 #endif -#ifdef _MSC_VER -# define FMT_MSC_VER _MSC_VER -#else -# define FMT_MSC_VER 0 -#endif - #if (defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 406) || \ FMT_CLANG_VERSION # pragma GCC diagnostic push @@ -96,7 +90,7 @@ # if FMT_EXCEPTIONS # define FMT_THROW(x) throw x # else -# define FMT_THROW(x) assert(false) +# define FMT_THROW(x) do { static_cast(sizeof(x)); assert(false); } while(false); # endif #endif diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index d946eb36055c..cdb01ad67080 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -139,11 +139,11 @@ using make_index_sequence = std::make_index_sequence; #else template struct integer_sequence { - typedef T value_type; + typedef T value_type; - static FMT_CONSTEXPR std::size_t size() { - return sizeof...(N); - } + static FMT_CONSTEXPR std::size_t size() { + return sizeof...(N); + } }; template diff --git a/support/cmake/cxx14.cmake b/support/cmake/cxx14.cmake index eb2c77e95721..083f7886417e 100644 --- a/support/cmake/cxx14.cmake +++ b/support/cmake/cxx14.cmake @@ -1,67 +1,52 @@ # C++14 feature support detection -if (NOT FMT_USE_CPP14) - return() -endif () - +include(CheckCXXSourceCompiles) include(CheckCXXCompilerFlag) -if (FMT_USE_CPP14) - check_cxx_compiler_flag(-std=c++14 HAVE_STD_CPP14_FLAG) - if (HAVE_STD_CPP14_FLAG) - # Check if including cmath works with -std=c++14 and -O3. - # It may not in MinGW due to bug http://ehc.ac/p/mingw/bugs/2250/. - set(CMAKE_REQUIRED_FLAGS "-std=c++14 -O3") - check_cxx_source_compiles(" - #include - int main() {}" FMT_CPP14_CMATH) - # Check if including works with -std=c++14. - # It may not in MinGW due to bug http://sourceforge.net/p/mingw/bugs/2024/. - check_cxx_source_compiles(" - #include - int main() {}" FMT_CPP14_UNISTD_H) - # Check if snprintf works with -std=c++14. It may not in MinGW. - check_cxx_source_compiles(" - #include - int main() { - char buffer[10]; - snprintf(buffer, 10, \"foo\"); - }" FMT_CPP14_SNPRINTF) - if (FMT_CPP14_CMATH AND FMT_CPP14_UNISTD_H AND FMT_CPP14_SNPRINTF) - set(CPP14_FLAG -std=c++14) - else () - check_cxx_compiler_flag(-std=gnu++14 HAVE_STD_GNUPP14_FLAG) - if (HAVE_STD_CPP14_FLAG) - set(CPP14_FLAG -std=gnu++14) - endif () - endif () - set(CMAKE_REQUIRED_FLAGS ) - else () - check_cxx_compiler_flag(-std=c++1y HAVE_STD_CPP1Y_FLAG) - if (HAVE_STD_CPP1Y_FLAG) - set(CPP14_FLAG -std=c++1y) - else () - # Fallback on c++11 if c++14 is not available. - check_cxx_compiler_flag(-std=c++11 HAVE_STD_CPP11_FLAG) - if (HAVE_STD_CPP11_FLAG) - set(CPP14_FLAG -std=c++11) - else () - check_cxx_compiler_flag(-std=c++0x HAVE_STD_CPP0X_FLAG) - if (HAVE_STD_CPP0X_FLAG) - set(CPP14_FLAG -std=c++0x) - endif () - endif () - endif () +if (NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) +endif() +message(STATUS "CXX_STANDARD: ${CMAKE_CXX_STANDARD}") + +if (CMAKE_CXX_STANDARD EQUAL 20) + check_cxx_compiler_flag(-std=c++20 has_std_20_flag) + check_cxx_compiler_flag(-std=c++2a has_std_2a_flag) + + if (has_std_20_flag) + set(CXX_STANDARD_FLAG -std=c++20) + elseif (has_std_2a_flag) + set(CXX_STANDARD_FLAG -std=c++2a) endif () -endif () +elseif (CMAKE_CXX_STANDARD EQUAL 17) + check_cxx_compiler_flag(-std=c++17 has_std_17_flag) + check_cxx_compiler_flag(-std=c++1z has_std_1z_flag) + + if (has_std_17_flag) + set(CXX_STANDARD_FLAG -std=c++17) + elseif (has_std_1z_flag) + set(CXX_STANDARD_FLAG -std=c++1z) + endif () +elseif (CMAKE_CXX_STANDARD EQUAL 14) + check_cxx_compiler_flag(-std=c++14 has_std_14_flag) + check_cxx_compiler_flag(-std=c++1y has_std_1y_flag) -if (CMAKE_CXX_STANDARD) - # Don't use -std compiler flag if CMAKE_CXX_STANDARD is specified. - set(CPP14_FLAG ) + if (has_std_14_flag) + set(CXX_STANDARD_FLAG -std=c++14) + elseif (has_std_1y_flag) + set(CXX_STANDARD_FLAG -std=c++1y) + endif () +elseif (CMAKE_CXX_STANDARD EQUAL 11) + check_cxx_compiler_flag(-std=c++11 has_std_14_flag) + check_cxx_compiler_flag(-std=c++0x has_std_0x_flag) + + if (has_std_11_flag) + set(CXX_STANDARD_FLAG -std=c++11) + elseif (has_std_0x_flag) + set(CXX_STANDARD_FLAG -std=c++0x) + endif () endif () -message(STATUS "CPP14_FLAG: ${CPP14_FLAG}") -set(CMAKE_REQUIRED_FLAGS ${CPP14_FLAG}) +set(CMAKE_REQUIRED_FLAGS ${CXX_STANDARD_FLAG}) # Check if variadic templates are working and not affected by GCC bug 39653: # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39653 @@ -69,17 +54,26 @@ check_cxx_source_compiles(" template struct S { typedef typename S::type type; }; int main() {}" SUPPORTS_VARIADIC_TEMPLATES) +if (NOT SUPPORTS_VARIADIC_TEMPLATES) + set (SUPPORTS_VARIADIC_TEMPLATES OFF) +endif () # Check if initializer lists are supported. check_cxx_source_compiles(" #include int main() {}" SUPPORTS_INITIALIZER_LIST) +if (NOT SUPPORTS_INITIALIZER_LIST) + set (SUPPORTS_INITIALIZER_LIST OFF) +endif () # Check if enum bases are available check_cxx_source_compiles(" enum C : char {A}; int main() {}" SUPPORTS_ENUM_BASE) +if (NOT SUPPORTS_ENUM_BASE) + set (SUPPORTS_ENUM_BASE OFF) +endif () # Check if type traits are available check_cxx_source_compiles(" @@ -87,11 +81,17 @@ check_cxx_source_compiles(" class C { void operator=(const C&); }; int main() { static_assert(!std::is_copy_assignable::value, \"\"); }" SUPPORTS_TYPE_TRAITS) +if (NOT SUPPORTS_TYPE_TRAITS) + set (SUPPORTS_TYPE_TRAITS OFF) +endif () # Check if user-defined literals are available check_cxx_source_compiles(" void operator\"\" _udl(long double); int main() {}" SUPPORTS_USER_DEFINED_LITERALS) +if (NOT SUPPORTS_USER_DEFINED_LITERALS) + set (SUPPORTS_USER_DEFINED_LITERALS OFF) +endif () set(CMAKE_REQUIRED_FLAGS ) diff --git a/support/travis-build.py b/support/travis-build.py index 6cdbf1b8e229..d71a7ae6cb4e 100755 --- a/support/travis-build.py +++ b/support/travis-build.py @@ -2,8 +2,8 @@ # Build the project on Travis CI. from __future__ import print_function -import errno, os, re, shutil, subprocess, sys, tempfile, urllib -from subprocess import call, check_call, check_output, Popen, PIPE, STDOUT +import errno, os, shutil, subprocess, sys, urllib +from subprocess import call, check_call, Popen, PIPE, STDOUT def rmtree_if_exists(dir): try: @@ -85,14 +85,12 @@ def install_dependencies(): # Configure library. makedirs_if_not_exist(build_dir) -common_cmake_flags = [ - '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build +cmake_flags = [ + '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build, + '-DCMAKE_CXX_STANDARD=' + standard ] -extra_cmake_flags = [] -if standard != '14': - extra_cmake_flags = ['-DCMAKE_CXX_STANDARD=' + standard] check_call(['cmake', '-DFMT_DOC=OFF', '-DFMT_PEDANTIC=ON', '-DFMT_WERROR=ON', fmt_dir] + - common_cmake_flags + extra_cmake_flags, cwd=build_dir) + cmake_flags, cwd=build_dir) # Build library. check_call(['make', '-j4'], cwd=build_dir) @@ -101,7 +99,7 @@ def install_dependencies(): env = os.environ.copy() env['CTEST_OUTPUT_ON_FAILURE'] = '1' if call(['make', 'test'], env=env, cwd=build_dir): - with open('Testing/Temporary/LastTest.log', 'r') as f: + with open(os.path.join(build_dir, 'Testing', 'Temporary', 'LastTest.log'), 'r') as f: print(f.read()) sys.exit(-1) @@ -110,7 +108,6 @@ def install_dependencies(): # Test installation. makedirs_if_not_exist(test_build_dir) -check_call(['cmake', '-DCMAKE_CXX_STANDARD=' + standard, - os.path.join(fmt_dir, "test", "find-package-test")] + - common_cmake_flags, cwd=test_build_dir) +check_call(['cmake', os.path.join(fmt_dir, "test", "find-package-test")] + + cmake_flags, cwd=test_build_dir) check_call(['make', '-j4'], cwd=test_build_dir) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8978a083f042..8d2ccc67e3d5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,7 +8,7 @@ add_library(gmock STATIC gmock-gtest-all.cc gmock/gmock.h gtest/gtest.h gtest/gtest-spi.h) target_compile_definitions(gmock PUBLIC GTEST_HAS_STD_WSTRING=1) -target_include_directories(gmock PUBLIC .) +target_include_directories(gmock SYSTEM PUBLIC . gmock gtest) find_package(Threads) if (Threads_FOUND) @@ -42,6 +42,7 @@ set(TEST_MAIN_SRC test-main.cc gtest-extra.cc gtest-extra.h util.cc) add_library(test-main STATIC ${TEST_MAIN_SRC}) target_compile_definitions(test-main PUBLIC FMT_USE_FILE_DESCRIPTORS=$) +target_include_directories(test-main SYSTEM PUBLIC gtest gmock) target_link_libraries(test-main gmock fmt) include(CheckCXXCompilerFlag) @@ -56,7 +57,7 @@ endif () # Use less strict pedantic flags for the tests because GMock doesn't compile # cleanly with -pedantic and -std=c++98. if (CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) - set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -Wno-long-long -Wno-variadic-macros) + #set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -Wno-long-long -Wno-variadic-macros) endif () function(add_fmt_executable name) @@ -79,6 +80,7 @@ function(add_fmt_test name) if (FMT_PEDANTIC) target_compile_options(${name} PRIVATE ${PEDANTIC_COMPILE_FLAGS}) endif () + target_include_directories(${name} SYSTEM PUBLIC gtest gmock) add_test(NAME ${name} COMMAND ${name}) endfunction() @@ -100,6 +102,10 @@ if (HAVE_OPEN) posix-mock-test PRIVATE ${PROJECT_SOURCE_DIR}/include) target_compile_definitions(posix-mock-test PRIVATE FMT_USE_FILE_DESCRIPTORS=1) target_link_libraries(posix-mock-test gmock) + target_include_directories(posix-mock-test SYSTEM PUBLIC gtest gmock) + if (FMT_PEDANTIC) + target_compile_options(posix-mock-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) + endif () add_test(NAME posix-mock-test COMMAND posix-mock-test) add_fmt_test(posix-test) endif () @@ -107,6 +113,7 @@ endif () add_fmt_executable(header-only-test header-only-test.cc header-only-test2.cc test-main.cc) target_link_libraries(header-only-test gmock) +target_include_directories(header-only-test SYSTEM PUBLIC gtest gmock) if (TARGET fmt-header-only) target_link_libraries(header-only-test fmt-header-only) else () @@ -122,8 +129,14 @@ if (HAVE_FNO_EXCEPTIONS_FLAG) target_include_directories( noexception-test PRIVATE ${PROJECT_SOURCE_DIR}/include) target_compile_options(noexception-test PRIVATE -fno-exceptions) + if (FMT_PEDANTIC) + target_compile_options(noexception-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) + endif () + target_include_directories(noexception-test SYSTEM PUBLIC gtest gmock) endif () +message(STATUS "FMT_PEDANTIC: ${FMT_PEDANTIC}") + if (FMT_PEDANTIC) # Test that the library compiles without windows.h. if (CMAKE_SYSTEM_NAME STREQUAL "Windows") @@ -131,8 +144,14 @@ if (FMT_PEDANTIC) target_include_directories( no-windows-h-test PRIVATE ${PROJECT_SOURCE_DIR}/include) target_compile_definitions(no-windows-h-test PRIVATE FMT_USE_WINDOWS_H=0) + if (FMT_PEDANTIC) + target_compile_options(no-windows-h-test ${PEDANTIC_COMPILE_FLAGS}) + endif () + target_include_directories(no-windows-h-test SYSTEM PUBLIC gtest gmock) endif () + message(STATUS USER_DEFINED_LITERALS: ${SUPPORTS_USER_DEFINED_LITERALS}) + add_test(compile-test ${CMAKE_CTEST_COMMAND} --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/compile-test" @@ -142,6 +161,8 @@ if (FMT_PEDANTIC) --build-options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" + "-DCXX_STANDARD_FLAG=${CXX_STANDARD_FLAG}" + "-DPEDANTIC_COMPILE_FLAGS=${PEDANTIC_COMPILE_FLAGS}" "-DSUPPORTS_USER_DEFINED_LITERALS=${SUPPORTS_USER_DEFINED_LITERALS}") # test if the targets are findable from the build directory @@ -156,6 +177,7 @@ if (FMT_PEDANTIC) "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" "-DFMT_DIR=${PROJECT_BINARY_DIR}" + "-DPEDANTIC_COMPILE_FLAGS=${PEDANTIC_COMPILE_FLAGS}" "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") # test if the targets are findable when add_subdirectory is used @@ -169,5 +191,6 @@ if (FMT_PEDANTIC) --build-options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" + "-DPEDANTIC_COMPILE_FLAGS=${PEDANTIC_COMPILE_FLAGS}" "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") endif () diff --git a/test/add-subdirectory-test/CMakeLists.txt b/test/add-subdirectory-test/CMakeLists.txt index d1edd8a52796..db7054bd8f99 100644 --- a/test/add-subdirectory-test/CMakeLists.txt +++ b/test/add-subdirectory-test/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.1.0) project(fmt-test) @@ -6,8 +6,12 @@ add_subdirectory(../.. fmt) add_executable(library-test "main.cc") target_link_libraries(library-test fmt::fmt) +target_compile_options(library-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) +target_include_directories(library-test PUBLIC SYSTEM .) if (TARGET fmt::fmt-header-only) add_executable(header-only-test "main.cc") target_link_libraries(header-only-test fmt::fmt-header-only) + target_compile_options(header-only-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) + target_include_directories(header-only-test PUBLIC SYSTEM .) endif () diff --git a/test/assert-test.cc b/test/assert-test.cc index 29c6d40bd51c..8af9b09f31d6 100644 --- a/test/assert-test.cc +++ b/test/assert-test.cc @@ -6,7 +6,7 @@ // For the license information refer to format.h. #include "fmt/core.h" -#include "gtest/gtest.h" +#include "gtest.h" #if GTEST_HAS_DEATH_TEST # define EXPECT_DEBUG_DEATH_IF_SUPPORTED(statement, regex) \ diff --git a/test/compile-test/CMakeLists.txt b/test/compile-test/CMakeLists.txt index dbf52b07657d..75a0c5a5e5e4 100644 --- a/test/compile-test/CMakeLists.txt +++ b/test/compile-test/CMakeLists.txt @@ -1,9 +1,12 @@ # Test if compile errors are produced where necessary. -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.1.0) include(CheckCXXSourceCompiles) +include(CheckCXXCompilerFlag) + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../../include) +set(CMAKE_REQUIRED_FLAGS ${CXX_STANDARD_FLAG} ${PEDANTIC_COMPILE_FLAGS}) function (generate_source result fragment) set(${result} " diff --git a/test/custom-formatter-test.cc b/test/custom-formatter-test.cc index dd513a59435f..919291add784 100644 --- a/test/custom-formatter-test.cc +++ b/test/custom-formatter-test.cc @@ -22,13 +22,21 @@ class custom_arg_formatter : using base::operator(); iterator operator()(double value) { - if (round(value * pow(10, spec().precision())) == 0) +#if FMT_GCC_VERSION +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + // Comparing a float to 0.0 is safe + if (round(value * pow(10, spec().precision())) == 0.0) value = 0; return base::operator()(value); +#if FMT_GCC_VERSION +#pragma GCC diagnostic pop +#endif } }; -std::string custom_vformat(fmt::string_view format_str, fmt::format_args args) { +static std::string custom_vformat(fmt::string_view format_str, fmt::format_args args) { fmt::memory_buffer buffer; // Pass custom argument formatter as a template arg to vwrite. fmt::vformat_to(buffer, format_str, args); diff --git a/test/find-package-test/CMakeLists.txt b/test/find-package-test/CMakeLists.txt index 40c075609602..513575570bb7 100644 --- a/test/find-package-test/CMakeLists.txt +++ b/test/find-package-test/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.1.0) project(fmt-test) @@ -6,8 +6,12 @@ find_package(FMT REQUIRED) add_executable(library-test main.cc) target_link_libraries(library-test fmt::fmt) +target_compile_options(library-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) +target_include_directories(library-test PUBLIC SYSTEM .) if (TARGET fmt::fmt-header-only) add_executable(header-only-test main.cc) target_link_libraries(header-only-test fmt::fmt-header-only) + target_compile_options(header-only-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) + target_include_directories(header-only-test PUBLIC SYSTEM .) endif () diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc index d7511cd0f39e..0daf00f5842b 100644 --- a/test/format-impl-test.cc +++ b/test/format-impl-test.cc @@ -16,7 +16,7 @@ #include #include -#include "gmock/gmock.h" +#include "gmock.h" #include "gtest-extra.h" #include "util.h" @@ -52,9 +52,9 @@ TEST(FormatTest, FormatNegativeNaN) { } TEST(FormatTest, StrError) { - char *message = 0; + char *message = nullptr; char buffer[BUFFER_SIZE]; - EXPECT_ASSERT(fmt::safe_strerror(EDOM, message = 0, 0), "invalid buffer"); + EXPECT_ASSERT(fmt::safe_strerror(EDOM, message = nullptr, 0), "invalid buffer"); EXPECT_ASSERT(fmt::safe_strerror(EDOM, message = buffer, 0), "invalid buffer"); buffer[0] = 'x'; diff --git a/test/format-test.cc b/test/format-test.cc index 0044390e7801..550b905ec1c0 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -14,7 +14,7 @@ #include #include -#include "gmock/gmock.h" +#include "gmock.h" // Test that the library compiles if None is defined to 0 as done by xlib.h. #define None 0 @@ -1024,7 +1024,7 @@ TEST(FormatterTest, FormatCString) { EXPECT_EQ("test", format("{0:s}", "test")); char nonconst[] = "nonconst"; EXPECT_EQ("nonconst", format("{0}", nonconst)); - EXPECT_THROW_MSG(format("{0}", reinterpret_cast(0)), + EXPECT_THROW_MSG(format("{0}", static_cast(nullptr)), format_error, "string pointer is null"); } @@ -1046,7 +1046,7 @@ TEST(FormatterTest, FormatUCharString) { TEST(FormatterTest, FormatPointer) { check_unknown_types(reinterpret_cast(0x1234), "p", "pointer"); - EXPECT_EQ("0x0", format("{0}", reinterpret_cast(0))); + EXPECT_EQ("0x0", format("{0}", static_cast(nullptr))); EXPECT_EQ("0x1234", format("{0}", reinterpret_cast(0x1234))); EXPECT_EQ("0x1234", format("{0:p}", reinterpret_cast(0x1234))); EXPECT_EQ("0x" + std::string(sizeof(void*) * CHAR_BIT / 4, 'f'), @@ -1148,7 +1148,7 @@ TEST(FormatterTest, FormatExamples) { FILE *ftest = safe_fopen(filename, "r"); if (ftest) fclose(ftest); int error_code = errno; - EXPECT_TRUE(ftest == 0); + EXPECT_TRUE(ftest == nullptr); EXPECT_SYSTEM_ERROR({ FILE *f = safe_fopen(filename, "r"); if (!f) @@ -1309,7 +1309,7 @@ TEST(StrTest, Convert) { EXPECT_EQ("2012-12-9", s); } -std::string vformat_message(int id, const char *format, fmt::format_args args) { +static std::string vformat_message(int id, const char *format, fmt::format_args args) { fmt::memory_buffer buffer; format_to(buffer, "[{}] ", id); vformat_to(buffer, format, args); @@ -1421,7 +1421,7 @@ class mock_arg_formatter: } }; -void custom_vformat(fmt::string_view format_str, fmt::format_args args) { +static void custom_vformat(fmt::string_view format_str, fmt::format_args args) { fmt::memory_buffer buffer; fmt::vformat_to(buffer, format_str, args); } @@ -1516,6 +1516,9 @@ TEST(FormatTest, FormatToN) { EXPECT_EQ(6u, result.size); EXPECT_EQ(buffer + 3, result.out); EXPECT_EQ("foox", fmt::string_view(buffer, 4)); + + // Workaround for potentially unused macro + static_cast(None); } #if FMT_USE_CONSTEXPR @@ -1794,12 +1797,14 @@ FMT_CONSTEXPR bool test_error(const char *fmt, const char *expected_error) { return equal(actual_error, expected_error); } +#define EXPECT_ERROR_NOARGS(fmt, error) \ + static_assert(test_error(fmt, error), "") #define EXPECT_ERROR(fmt, error, ...) \ static_assert(test_error<__VA_ARGS__>(fmt, error), "") TEST(FormatTest, FormatStringErrors) { - EXPECT_ERROR("foo", nullptr); - EXPECT_ERROR("}", "unmatched '}' in format string"); + EXPECT_ERROR_NOARGS("foo", nullptr); + EXPECT_ERROR_NOARGS("}", "unmatched '}' in format string"); EXPECT_ERROR("{0:s", "unknown format specifier", Date); #ifndef _MSC_VER // This causes an internal compiler error in MSVC2017. @@ -1807,7 +1812,7 @@ TEST(FormatTest, FormatStringErrors) { EXPECT_ERROR("{:{<}", "invalid fill character '{'", int); EXPECT_ERROR("{:10000000000}", "number is too big", int); EXPECT_ERROR("{:.10000000000}", "number is too big", int); - EXPECT_ERROR("{:x}", "argument index out of range"); + EXPECT_ERROR_NOARGS("{:x}", "argument index out of range"); EXPECT_ERROR("{:=}", "format specifier requires numeric argument", const char *); EXPECT_ERROR("{:+}", "format specifier requires numeric argument", @@ -1834,15 +1839,15 @@ TEST(FormatTest, FormatStringErrors) { EXPECT_ERROR("{:s}", "invalid type specifier", void *); #endif EXPECT_ERROR("{foo", "missing '}' in format string", int); - EXPECT_ERROR("{10000000000}", "number is too big"); - EXPECT_ERROR("{0x}", "invalid format string"); - EXPECT_ERROR("{-}", "invalid format string"); + EXPECT_ERROR_NOARGS("{10000000000}", "number is too big"); + EXPECT_ERROR_NOARGS("{0x}", "invalid format string"); + EXPECT_ERROR_NOARGS("{-}", "invalid format string"); EXPECT_ERROR("{:{0x}}", "invalid format string", int); EXPECT_ERROR("{:{-}}", "invalid format string", int); EXPECT_ERROR("{:.{0x}}", "invalid format string", int); EXPECT_ERROR("{:.{-}}", "invalid format string", int); EXPECT_ERROR("{:.x}", "missing precision specifier", int); - EXPECT_ERROR("{}", "argument index out of range"); + EXPECT_ERROR_NOARGS("{}", "argument index out of range"); EXPECT_ERROR("{1}", "argument index out of range", int); EXPECT_ERROR("{1}{}", "cannot switch from manual to automatic argument indexing", diff --git a/test/gmock-gtest-all.cc b/test/gmock-gtest-all.cc index 1a63a8ce7eec..7dca684cd50f 100644 --- a/test/gmock-gtest-all.cc +++ b/test/gmock-gtest-all.cc @@ -36,7 +36,7 @@ // This line ensures that gtest.h can be compiled on its own, even // when it's fused. -#include "gtest/gtest.h" +#include "gtest.h" // The following lines pull in the real gtest *.cc files. // Copyright 2005, Google Inc. diff --git a/test/gmock/gmock.h b/test/gmock/gmock.h index 8fd9c90c9542..2a9cbd532558 100644 --- a/test/gmock/gmock.h +++ b/test/gmock/gmock.h @@ -235,7 +235,7 @@ // Most of the types needed for porting Google Mock are also required // for Google Test and are defined in gtest-port.h. -#include "gtest/gtest.h" +#include "gtest.h" // To avoid conditional compilation everywhere, we make it // gmock-port.h's responsibility to #include the header implementing diff --git a/test/gtest-extra-test.cc b/test/gtest-extra-test.cc index 8e42d8e21647..13596b18923b 100644 --- a/test/gtest-extra-test.cc +++ b/test/gtest-extra-test.cc @@ -340,10 +340,10 @@ TEST(OutputRedirectTest, FlushErrorInCtor) { // Put a character in a file buffer. EXPECT_EQ('x', fputc('x', f.get())); FMT_POSIX(close(write_fd)); - scoped_ptr redir; + scoped_ptr redir{nullptr}; EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())), EBADF, "cannot flush stream"); - redir.reset(); + redir.reset(nullptr); write_copy.dup2(write_fd); // "undo" close or dtor will fail } @@ -352,7 +352,7 @@ TEST(OutputRedirectTest, DupErrorInCtor) { int fd = (f.fileno)(); file copy = file::dup(fd); FMT_POSIX(close(fd)); - scoped_ptr redir; + scoped_ptr redir{nullptr}; EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())), EBADF, fmt::format("cannot duplicate file descriptor {}", fd)); copy.dup2(fd); // "undo" close or dtor will fail @@ -403,7 +403,7 @@ TEST(OutputRedirectTest, ErrorInDtor) { // output in EXPECT_STDERR and the second close will break output // redirection. FMT_POSIX(close(write_fd)); - SUPPRESS_ASSERT(redir.reset()); + SUPPRESS_ASSERT(redir.reset(nullptr)); }, format_system_error(EBADF, "cannot flush stream")); write_copy.dup2(write_fd); // "undo" close or dtor of buffered_file will fail } diff --git a/test/gtest-extra.cc b/test/gtest-extra.cc index 2c4c34a75773..2e5ea3e3bc08 100644 --- a/test/gtest-extra.cc +++ b/test/gtest-extra.cc @@ -75,7 +75,7 @@ std::string read(file &f, std::size_t count) { do { n = f.read(&buffer[offset], count - offset); // We can't read more than size_t bytes since count has type size_t. - offset += static_cast(n); + offset += n; } while (offset < count && n != 0); buffer.resize(offset); return buffer; diff --git a/test/gtest-extra.h b/test/gtest-extra.h index db0323d2ffac..c3728f535ae0 100644 --- a/test/gtest-extra.h +++ b/test/gtest-extra.h @@ -9,7 +9,7 @@ #define FMT_GTEST_EXTRA_H_ #include -#include +#include "gmock.h" #include "fmt/core.h" @@ -155,7 +155,7 @@ std::string read(fmt::file &f, std::size_t count); template struct ScopedMock : testing::StrictMock { ScopedMock() { Mock::instance = this; } - ~ScopedMock() { Mock::instance = 0; } + ~ScopedMock() { Mock::instance = nullptr; } }; #endif // FMT_GTEST_EXTRA_H_ diff --git a/test/mock-allocator.h b/test/mock-allocator.h index e32b381604a5..58e157a5b85d 100644 --- a/test/mock-allocator.h +++ b/test/mock-allocator.h @@ -8,7 +8,7 @@ #ifndef FMT_MOCK_ALLOCATOR_H_ #define FMT_MOCK_ALLOCATOR_H_ -#include "gmock/gmock.h" +#include "gmock.h" template class MockAllocator { @@ -28,7 +28,7 @@ class AllocatorRef { public: typedef typename Allocator::value_type value_type; - explicit AllocatorRef(Allocator *alloc = 0) : alloc_(alloc) {} + explicit AllocatorRef(Allocator *alloc = nullptr) : alloc_(alloc) {} AllocatorRef(const AllocatorRef &other) : alloc_(other.alloc_) {} @@ -41,7 +41,7 @@ class AllocatorRef { private: void move(AllocatorRef &other) { alloc_ = other.alloc_; - other.alloc_ = 0; + other.alloc_ = nullptr; } public: diff --git a/test/ostream-test.cc b/test/ostream-test.cc index ffc2f8b2604a..85fea764062c 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -8,29 +8,29 @@ #include "fmt/ostream.h" #include -#include "gmock/gmock.h" +#include "gmock.h" #include "gtest-extra.h" #include "util.h" using fmt::format; using fmt::format_error; -std::ostream &operator<<(std::ostream &os, const Date &d) { +static std::ostream &operator<<(std::ostream &os, const Date &d) { os << d.year() << '-' << d.month() << '-' << d.day(); return os; } -std::wostream &operator<<(std::wostream &os, const Date &d) { +static std::wostream &operator<<(std::wostream &os, const Date &d) { os << d.year() << L'-' << d.month() << L'-' << d.day(); return os; } enum TestEnum {}; -std::ostream &operator<<(std::ostream &os, TestEnum) { +static std::ostream &operator<<(std::ostream &os, TestEnum) { return os << "TestEnum"; } -std::wostream &operator<<(std::wostream &os, TestEnum) { +static std::wostream &operator<<(std::wostream &os, TestEnum) { return os << L"TestEnum"; } @@ -95,7 +95,7 @@ TEST(OStreamTest, FormatSpecs) { } struct EmptyTest {}; -std::ostream &operator<<(std::ostream &os, EmptyTest) { +static std::ostream &operator<<(std::ostream &os, EmptyTest) { return os << ""; } @@ -145,7 +145,7 @@ TEST(OStreamTest, WriteToOStreamMaxSize) { } os(streambuf); testing::InSequence sequence; - const char *data = 0; + const char *data = nullptr; std::size_t size = max_size; do { typedef std::make_unsigned::type ustreamsize; @@ -154,7 +154,7 @@ TEST(OStreamTest, WriteToOStreamMaxSize) { EXPECT_CALL(streambuf, xsputn(data, static_cast(n))) .WillOnce(testing::Return(max_streamsize)); data += n; - size -= static_cast(n); + size -= n; } while (size != 0); fmt::internal::write(os, buffer); } diff --git a/test/posix-mock-test.cc b/test/posix-mock-test.cc index f69313c3dc31..9218816f26a0 100644 --- a/test/posix-mock-test.cc +++ b/test/posix-mock-test.cc @@ -6,7 +6,9 @@ // For the license information refer to format.h. // Disable bogus MSVC warnings. -#define _CRT_SECURE_NO_WARNINGS +#ifdef _MSC_VER +# define _CRT_SECURE_NO_WARNINGS +#endif #include "posix-mock.h" #include "../src/posix.cc" @@ -21,7 +23,7 @@ # undef ERROR #endif -#include "gmock/gmock.h" +#include "gmock.h" #include "gtest-extra.h" #include "util.h" @@ -131,7 +133,7 @@ int test::dup2(int fildes, int fildes2) { } FILE *test::fdopen(int fildes, const char *mode) { - EMULATE_EINTR(fdopen, 0); + EMULATE_EINTR(fdopen, nullptr); return ::FMT_POSIX(fdopen(fildes, mode)); } @@ -160,7 +162,7 @@ int test::pipe(int *pfds, unsigned psize, int textmode) { #endif FILE *test::fopen(const char *filename, const char *mode) { - EMULATE_EINTR(fopen, 0); + EMULATE_EINTR(fopen, nullptr); return ::fopen(filename, mode); } @@ -193,7 +195,7 @@ int (test::fileno)(FILE *stream) { # define EXPECT_EQ_POSIX(expected, actual) #endif -void write_file(fmt::cstring_view filename, fmt::string_view content) { +static void write_file(fmt::cstring_view filename, fmt::string_view content) { fmt::buffered_file f(filename, "w"); f.print("{}", content); } @@ -214,7 +216,7 @@ TEST(UtilTest, GetPageSize) { TEST(FileTest, OpenRetry) { write_file("test", "there must be something here"); - scoped_ptr f; + scoped_ptr f{nullptr}; EXPECT_RETRY(f.reset(new file("test", file::RDONLY)), open, "cannot open file test"); #ifndef _WIN32 @@ -230,7 +232,7 @@ TEST(FileTest, CloseNoRetryInDtor) { int saved_close_count = 0; EXPECT_WRITE(stderr, { close_count = 1; - f.reset(); + f.reset(nullptr); saved_close_count = close_count; close_count = 0; }, format_system_error(EINTR, "cannot close file") + "\n"); @@ -383,7 +385,7 @@ TEST(FileTest, FdopenNoRetry) { TEST(BufferedFileTest, OpenRetry) { write_file("test", "there must be something here"); - scoped_ptr f; + scoped_ptr f{nullptr}; EXPECT_RETRY(f.reset(new buffered_file("test", "r")), fopen, "cannot open file test"); #ifndef _WIN32 @@ -400,7 +402,7 @@ TEST(BufferedFileTest, CloseNoRetryInDtor) { int saved_fclose_count = 0; EXPECT_WRITE(stderr, { fclose_count = 1; - f.reset(); + f.reset(nullptr); saved_fclose_count = fclose_count; fclose_count = 0; }, format_system_error(EINTR, "cannot close file") + "\n"); @@ -436,8 +438,9 @@ TEST(ScopedMock, Scope) { ScopedMock mock; EXPECT_EQ(&mock, TestMock::instance); TestMock © = mock; + static_cast(copy); } - EXPECT_EQ(0, TestMock::instance); + EXPECT_EQ(nullptr, TestMock::instance); } #ifdef FMT_LOCALE @@ -504,7 +507,7 @@ TEST(LocaleTest, Locale) { #endif ScopedMock mock; LocaleType impl = reinterpret_cast(42); - EXPECT_CALL(mock, newlocale(LC_NUMERIC_MASK, StrEq("C"), 0)) + EXPECT_CALL(mock, newlocale(LC_NUMERIC_MASK, StrEq("C"), nullptr)) .WillOnce(Return(impl)); EXPECT_CALL(mock, freelocale(impl)); fmt::Locale locale; diff --git a/test/posix-test.cc b/test/posix-test.cc index 6f65ec38f499..f23d06b37bb0 100644 --- a/test/posix-test.cc +++ b/test/posix-test.cc @@ -23,12 +23,12 @@ using fmt::file; using testing::internal::scoped_ptr; // Checks if the file is open by reading one character from it. -bool isopen(int fd) { +static bool isopen(int fd) { char buffer; return FMT_POSIX(read(fd, &buffer, 1)) == 1; } -bool isclosed(int fd) { +static bool isclosed(int fd) { char buffer; std::streamsize result = 0; SUPPRESS_ASSERT(result = FMT_POSIX(read(fd, &buffer, 1))); @@ -36,7 +36,7 @@ bool isclosed(int fd) { } // Opens a file for reading. -file open_file() { +static file open_file() { file read_end, write_end; file::pipe(read_end, write_end); write_end.write(FILE_CONTENT, std::strlen(FILE_CONTENT)); @@ -45,7 +45,7 @@ file open_file() { } // Attempts to write a string to a file. -void write(file &f, fmt::string_view s) { +static void write(file &f, fmt::string_view s) { std::size_t num_chars_left = s.size(); const char *ptr = s.data(); do { @@ -53,32 +53,32 @@ void write(file &f, fmt::string_view s) { ptr += count; // We can't write more than size_t bytes since num_chars_left // has type size_t. - num_chars_left -= static_cast(count); + num_chars_left -= count; } while (num_chars_left != 0); } TEST(BufferedFileTest, DefaultCtor) { buffered_file f; - EXPECT_TRUE(f.get() == 0); + EXPECT_TRUE(f.get() == nullptr); } TEST(BufferedFileTest, MoveCtor) { buffered_file bf = open_buffered_file(); FILE *fp = bf.get(); - EXPECT_TRUE(fp != 0); + EXPECT_TRUE(fp != nullptr); buffered_file bf2(std::move(bf)); EXPECT_EQ(fp, bf2.get()); - EXPECT_TRUE(bf.get() == 0); + EXPECT_TRUE(bf.get() == nullptr); } TEST(BufferedFileTest, MoveAssignment) { buffered_file bf = open_buffered_file(); FILE *fp = bf.get(); - EXPECT_TRUE(fp != 0); + EXPECT_TRUE(fp != nullptr); buffered_file bf2; bf2 = std::move(bf); EXPECT_EQ(fp, bf2.get()); - EXPECT_TRUE(bf.get() == 0); + EXPECT_TRUE(bf.get() == nullptr); } TEST(BufferedFileTest, MoveAssignmentClosesFile) { @@ -90,13 +90,13 @@ TEST(BufferedFileTest, MoveAssignmentClosesFile) { } TEST(BufferedFileTest, MoveFromTemporaryInCtor) { - FILE *fp = 0; + FILE *fp = nullptr; buffered_file f(open_buffered_file(&fp)); EXPECT_EQ(fp, f.get()); } TEST(BufferedFileTest, MoveFromTemporaryInAssignment) { - FILE *fp = 0; + FILE *fp = nullptr; buffered_file f; f = open_buffered_file(&fp); EXPECT_EQ(fp, f.get()); @@ -126,7 +126,7 @@ TEST(BufferedFileTest, CloseErrorInDtor) { // output in EXPECT_STDERR and the second close will break output // redirection. FMT_POSIX(close(f->fileno())); - SUPPRESS_ASSERT(f.reset()); + SUPPRESS_ASSERT(f.reset(nullptr)); }, format_system_error(EBADF, "cannot close file") + "\n"); } @@ -134,7 +134,7 @@ TEST(BufferedFileTest, Close) { buffered_file f = open_buffered_file(); int fd = f.fileno(); f.close(); - EXPECT_TRUE(f.get() == 0); + EXPECT_TRUE(f.get() == nullptr); EXPECT_TRUE(isclosed(fd)); } @@ -142,7 +142,7 @@ TEST(BufferedFileTest, CloseError) { buffered_file f = open_buffered_file(); FMT_POSIX(close(f.fileno())); EXPECT_SYSTEM_ERROR_NOASSERT(f.close(), EBADF, "cannot close file"); - EXPECT_TRUE(f.get() == 0); + EXPECT_TRUE(f.get() == nullptr); } TEST(BufferedFileTest, Fileno) { @@ -209,7 +209,7 @@ TEST(FileTest, MoveAssignmentClosesFile) { EXPECT_TRUE(isclosed(old_fd)); } -file OpenBufferedFile(int &fd) { +static file OpenBufferedFile(int &fd) { file f = open_file(); fd = f.descriptor(); return f; @@ -253,7 +253,7 @@ TEST(FileTest, CloseErrorInDtor) { // output in EXPECT_STDERR and the second close will break output // redirection. FMT_POSIX(close(f->descriptor())); - SUPPRESS_ASSERT(f.reset()); + SUPPRESS_ASSERT(f.reset(nullptr)); }, format_system_error(EBADF, "cannot close file") + "\n"); } diff --git a/test/printf-test.cc b/test/printf-test.cc index c15a32012bfa..f9208c16fcb8 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -20,13 +20,13 @@ using fmt::format_error; const unsigned BIG_NUM = INT_MAX + 1u; // Makes format string argument positional. -std::string make_positional(fmt::string_view format) { +static std::string make_positional(fmt::string_view format) { std::string s(format.data(), format.size()); s.replace(s.find('%'), 1, "%1$"); return s; } -std::wstring make_positional(fmt::wstring_view format) { +static std::wstring make_positional(fmt::wstring_view format) { std::wstring s(format.data(), format.size()); s.replace(s.find(L'%'), 1, L"%1$"); return s; @@ -410,7 +410,7 @@ TEST(PrintfTest, Inf) { double inf = std::numeric_limits::infinity(); for (const char* type = "fega"; *type; ++type) { EXPECT_PRINTF("inf", fmt::format("%{}", *type), inf); - char upper = std::toupper(*type); + char upper = static_cast(std::toupper(*type)); EXPECT_PRINTF("INF", fmt::format("%{}", upper), inf); } } @@ -426,11 +426,11 @@ TEST(PrintfTest, Char) { TEST(PrintfTest, String) { EXPECT_PRINTF("abc", "%s", "abc"); - const char *null_str = 0; + const char *null_str = nullptr; EXPECT_PRINTF("(null)", "%s", null_str); EXPECT_PRINTF(" (null)", "%10s", null_str); EXPECT_PRINTF(L"abc", L"%s", L"abc"); - const wchar_t *null_wstr = 0; + const wchar_t *null_wstr = nullptr; EXPECT_PRINTF(L"(null)", L"%s", null_wstr); EXPECT_PRINTF(L" (null)", L"%10s", null_wstr); } @@ -439,22 +439,22 @@ TEST(PrintfTest, Pointer) { int n; void *p = &n; EXPECT_PRINTF(fmt::format("{}", p), "%p", p); - p = 0; + p = nullptr; EXPECT_PRINTF("(nil)", "%p", p); EXPECT_PRINTF(" (nil)", "%10p", p); const char *s = "test"; EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s); - const char *null_str = 0; + const char *null_str = nullptr; EXPECT_PRINTF("(nil)", "%p", null_str); p = &n; EXPECT_PRINTF(fmt::format(L"{}", p), L"%p", p); - p = 0; + p = nullptr; EXPECT_PRINTF(L"(nil)", L"%p", p); EXPECT_PRINTF(L" (nil)", L"%10p", p); const wchar_t *w = L"test"; EXPECT_PRINTF(fmt::format(L"{:p}", w), L"%p", w); - const wchar_t *null_wstr = 0; + const wchar_t *null_wstr = nullptr; EXPECT_PRINTF(L"(nil)", L"%p", null_wstr); } diff --git a/test/ranges-test.cc b/test/ranges-test.cc index c27833f2aaab..efe4f4924aa2 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -11,7 +11,7 @@ #include "fmt/ranges.h" -#include "gtest/gtest.h" +#include "gtest.h" #include #include diff --git a/test/test-main.cc b/test/test-main.cc index 2749a64486a6..bc0be76acfe8 100644 --- a/test/test-main.cc +++ b/test/test-main.cc @@ -6,7 +6,7 @@ // For the license information refer to format.h. #include -#include +#include "gtest.h" #ifdef _WIN32 # include diff --git a/test/time-test.cc b/test/time-test.cc index e285223bc627..bc05f24c4f18 100644 --- a/test/time-test.cc +++ b/test/time-test.cc @@ -9,7 +9,7 @@ #define _CRT_SECURE_NO_WARNINGS #endif -#include "gmock/gmock.h" +#include "gmock.h" #include "fmt/time.h" TEST(TimeTest, Format) { @@ -26,7 +26,7 @@ TEST(TimeTest, GrowBuffer) { for (int i = 0; i < 30; ++i) s += "%c"; s += "}\n"; - std::time_t t = std::time(0); + std::time_t t = std::time(nullptr); fmt::format(s, *std::localtime(&t)); } @@ -34,7 +34,7 @@ TEST(TimeTest, EmptyResult) { EXPECT_EQ("", fmt::format("{}", std::tm())); } -bool EqualTime(const std::tm &lhs, const std::tm &rhs) { +static bool EqualTime(const std::tm &lhs, const std::tm &rhs) { return lhs.tm_sec == rhs.tm_sec && lhs.tm_min == rhs.tm_min && lhs.tm_hour == rhs.tm_hour && @@ -47,13 +47,13 @@ bool EqualTime(const std::tm &lhs, const std::tm &rhs) { } TEST(TimeTest, LocalTime) { - std::time_t t = std::time(0); + std::time_t t = std::time(nullptr); std::tm tm = *std::localtime(&t); EXPECT_TRUE(EqualTime(tm, fmt::localtime(t))); } TEST(TimeTest, GMTime) { - std::time_t t = std::time(0); + std::time_t t = std::time(nullptr); std::tm tm = *std::gmtime(&t); EXPECT_TRUE(EqualTime(tm, fmt::gmtime(t))); } diff --git a/test/util-test.cc b/test/util-test.cc index d0fdefec7a4b..beab4ae79239 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -17,7 +17,7 @@ # include #endif -#include "gmock/gmock.h" +#include "gmock.h" #include "gtest-extra.h" #include "mock-allocator.h" #include "util.h" @@ -71,8 +71,8 @@ struct formatter { }; FMT_END_NAMESPACE -void CheckForwarding( - MockAllocator &alloc, AllocatorRef< MockAllocator > &ref) { +static void CheckForwarding( + MockAllocator &alloc, AllocatorRef> &ref) { int mem; // Check if value_type is properly defined. AllocatorRef< MockAllocator >::value_type *ptr = &mem; @@ -92,7 +92,7 @@ TEST(AllocatorTest, AllocatorRef) { TestAllocatorRef ref2(ref); CheckForwarding(alloc, ref2); TestAllocatorRef ref3; - EXPECT_EQ(0, ref3.get()); + EXPECT_EQ(nullptr, ref3.get()); ref3 = ref; CheckForwarding(alloc, ref3); } @@ -112,7 +112,7 @@ TEST(BufferTest, Nonmoveable) { // A test buffer with a dummy grow method. template struct TestBuffer : basic_buffer { - void grow(std::size_t capacity) { this->set(0, capacity); } + void grow(std::size_t capacity) { this->set(nullptr, capacity); } }; template @@ -132,23 +132,23 @@ struct MockBuffer : basic_buffer { TEST(BufferTest, Ctor) { { MockBuffer buffer; - EXPECT_EQ(0, &buffer[0]); - EXPECT_EQ(0u, buffer.size()); - EXPECT_EQ(0u, buffer.capacity()); + EXPECT_EQ(nullptr, &buffer[0]); + EXPECT_EQ(static_cast(0), buffer.size()); + EXPECT_EQ(static_cast(0), buffer.capacity()); } { int dummy; MockBuffer buffer(&dummy); EXPECT_EQ(&dummy, &buffer[0]); - EXPECT_EQ(0u, buffer.size()); - EXPECT_EQ(0u, buffer.capacity()); + EXPECT_EQ(static_cast(0), buffer.size()); + EXPECT_EQ(static_cast(0), buffer.capacity()); } { int dummy; std::size_t capacity = std::numeric_limits::max(); MockBuffer buffer(&dummy, capacity); EXPECT_EQ(&dummy, &buffer[0]); - EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(static_cast(0), buffer.size()); EXPECT_EQ(capacity, buffer.capacity()); } } @@ -201,7 +201,7 @@ TEST(BufferTest, Clear) { TestBuffer buffer; buffer.resize(20); buffer.resize(0); - EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(static_cast(0), buffer.size()); EXPECT_EQ(20u, buffer.capacity()); } @@ -231,7 +231,7 @@ TEST(BufferTest, AppendAllocatesEnoughStorage) { TEST(MemoryBufferTest, Ctor) { basic_memory_buffer buffer; - EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(static_cast(0), buffer.size()); EXPECT_EQ(123u, buffer.capacity()); } @@ -239,7 +239,7 @@ TEST(MemoryBufferTest, Ctor) { typedef AllocatorRef< std::allocator > TestAllocator; -void check_move_buffer(const char *str, +static void check_move_buffer(const char *str, basic_memory_buffer &buffer) { std::allocator *alloc = buffer.get_allocator().get(); basic_memory_buffer buffer2(std::move(buffer)); @@ -248,7 +248,7 @@ void check_move_buffer(const char *str, EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size())); EXPECT_EQ(5u, buffer2.capacity()); // Move should transfer allocator. - EXPECT_EQ(0, buffer.get_allocator().get()); + EXPECT_EQ(nullptr, buffer.get_allocator().get()); EXPECT_EQ(alloc, buffer2.get_allocator().get()); } @@ -273,7 +273,7 @@ TEST(MemoryBufferTest, MoveCtor) { EXPECT_GT(buffer2.capacity(), 5u); } -void check_move_assign_buffer( +static void check_move_assign_buffer( const char *str, basic_memory_buffer &buffer) { basic_memory_buffer buffer2; buffer2 = std::move(buffer); @@ -335,7 +335,7 @@ TEST(MemoryBufferTest, Grow) { TEST(MemoryBufferTest, Allocator) { typedef AllocatorRef< MockAllocator > TestAllocator; basic_memory_buffer buffer; - EXPECT_EQ(0, buffer.get_allocator().get()); + EXPECT_EQ(nullptr, buffer.get_allocator().get()); StrictMock< MockAllocator > alloc; char mem; { @@ -376,7 +376,7 @@ TEST(MemoryBufferTest, ExceptionInDeallocate) { TEST(FixedBufferTest, Ctor) { char array[10] = "garbage"; fmt::basic_fixed_buffer buffer(array, sizeof(array)); - EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(static_cast(0), buffer.size()); EXPECT_EQ(10u, buffer.capacity()); EXPECT_EQ(array, buffer.data()); } @@ -384,7 +384,7 @@ TEST(FixedBufferTest, Ctor) { TEST(FixedBufferTest, CompileTimeSizeCtor) { char array[10] = "garbage"; fmt::basic_fixed_buffer buffer(array); - EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(static_cast(0), buffer.size()); EXPECT_EQ(10u, buffer.capacity()); EXPECT_EQ(array, buffer.data()); } @@ -439,7 +439,7 @@ struct custom_context { const char *format(const T &, custom_context& ctx) { ctx.called = true; - return 0; + return nullptr; } }; }; @@ -583,8 +583,8 @@ TEST(UtilTest, WStringArg) { } TEST(UtilTest, PointerArg) { - void *p = 0; - const void *cp = 0; + void *p = nullptr; + const void *cp = nullptr; CHECK_ARG_(char, cp, p); CHECK_ARG_(wchar_t, cp, p); CHECK_ARG(cp, ); @@ -772,7 +772,7 @@ TEST(UtilTest, FormatSystemError) { fmt::print("warning: std::allocator allocates {} chars", max_size); return; } - fmt::format_system_error(message, EDOM, fmt::string_view(0, max_size)); + fmt::format_system_error(message, EDOM, fmt::string_view(nullptr, max_size)); EXPECT_EQ(fmt::format("error {}", EDOM), to_string(message)); } @@ -868,7 +868,7 @@ TEST(UtilTest, IsEnumConvertibleToInt) { #endif TEST(UtilTest, ParseNonnegativeInt) { - if (std::numeric_limits::max() != (1 << 31)) { + if (std::numeric_limits::max() != static_cast(static_cast(1) << 31)) { fmt::print("Skipping parse_nonnegative_int test\n"); return; } diff --git a/test/util.h b/test/util.h index a4440bb0d73a..c0af03c78c56 100644 --- a/test/util.h +++ b/test/util.h @@ -35,7 +35,7 @@ std::string get_system_error(int error_code); extern const char *const FILE_CONTENT; // Opens a buffered file for reading. -fmt::buffered_file open_buffered_file(FILE **fp = 0); +fmt::buffered_file open_buffered_file(FILE **fp = nullptr); inline FILE *safe_fopen(const char *filename, const char *mode) { #if defined(_WIN32) && !defined(__MINGW32__) From 25f9b090ec9ca5cd0d1a8e311a67aff0fe03dc92 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Tue, 5 Jun 2018 02:29:25 +0300 Subject: [PATCH 13/15] Fix warnings from edits to master --- include/fmt/format.h | 14 +++++++------- support/cmake/cxx14.cmake | 2 +- test/CMakeLists.txt | 2 -- test/posix-mock-test.cc | 14 +++++++++++--- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 24159f9f5c0a..018f1aafecc4 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -283,12 +283,12 @@ class fp { typedef uint64_t significand_type; // All sizes are in bits. - static constexpr int char_size = std::numeric_limits::digits; + static FMT_CONSTEXPR_DECL const int char_size = std::numeric_limits::digits; // Subtract 1 to account for an implicit most significant bit in the // normalized form. - static constexpr int double_significand_size = + static FMT_CONSTEXPR_DECL const int double_significand_size = std::numeric_limits::digits - 1; - static constexpr uint64_t implicit_bit = 1ull << double_significand_size; + static FMT_CONSTEXPR_DECL const uint64_t implicit_bit = 1ull << double_significand_size; public: significand_type f; @@ -317,7 +317,7 @@ class fp { f += implicit_bit; else biased_e = 1; // Subnormals use biased exponent 1 (min exponent). - e = biased_e - exponent_bias - double_significand_size; + e = static_cast(biased_e - exponent_bias - double_significand_size); } // Normalizes the value converted from double and multiplied by (1 << SHIFT). @@ -2660,7 +2660,7 @@ class basic_writer { }; struct double_writer { - unsigned n; + size_t n; char sign; basic_memory_buffer &buffer; @@ -2914,7 +2914,7 @@ void basic_writer::write_double(T value, const format_specs &spec) { internal::fp product = fp_value * dec_pow; // Generate output. internal::fp one(1ull << -product.e, product.e); - uint32_t hi = product.f >> -one.e; + uint64_t hi = product.f >> -one.e; uint64_t f = product.f & (one.f - 1); typedef back_insert_range> range; basic_writer w{range(buffer)}; @@ -2934,7 +2934,7 @@ void basic_writer::write_double(T value, const format_specs &spec) { normalized_spec.type_ = handler.type; write_double_sprintf(value, normalized_spec, buffer); } - unsigned n = buffer.size(); + size_t n = buffer.size(); align_spec as = spec; if (spec.align() == ALIGN_NUMERIC) { if (sign) { diff --git a/support/cmake/cxx14.cmake b/support/cmake/cxx14.cmake index 083f7886417e..1866cdcc5f2c 100644 --- a/support/cmake/cxx14.cmake +++ b/support/cmake/cxx14.cmake @@ -36,7 +36,7 @@ elseif (CMAKE_CXX_STANDARD EQUAL 14) set(CXX_STANDARD_FLAG -std=c++1y) endif () elseif (CMAKE_CXX_STANDARD EQUAL 11) - check_cxx_compiler_flag(-std=c++11 has_std_14_flag) + check_cxx_compiler_flag(-std=c++11 has_std_11_flag) check_cxx_compiler_flag(-std=c++0x has_std_0x_flag) if (has_std_11_flag) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8d2ccc67e3d5..78e952e28ac6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -150,8 +150,6 @@ if (FMT_PEDANTIC) target_include_directories(no-windows-h-test SYSTEM PUBLIC gtest gmock) endif () - message(STATUS USER_DEFINED_LITERALS: ${SUPPORTS_USER_DEFINED_LITERALS}) - add_test(compile-test ${CMAKE_CTEST_COMMAND} --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/compile-test" diff --git a/test/posix-mock-test.cc b/test/posix-mock-test.cc index 9218816f26a0..83a9ac3c2569 100644 --- a/test/posix-mock-test.cc +++ b/test/posix-mock-test.cc @@ -475,7 +475,13 @@ double _strtod_l(const char *nptr, char **endptr, _locale_t locale) { # pragma warning(pop) #endif -LocaleType newlocale(int category_mask, const char *locale, LocaleType base) { +#if defined(__THROW) && FMT_GCC_VERSION > 0 && FMT_GCC_VERSION <= 408 +#define FMT_LOCALE_THROW __THROW +#else +#define FMT_LOCALE_THROW +#endif + +LocaleType newlocale(int category_mask, const char *locale, LocaleType base) FMT_LOCALE_THROW { return LocaleMock::instance->newlocale(category_mask, locale, base); } @@ -485,15 +491,17 @@ typedef int FreeLocaleResult; typedef void FreeLocaleResult; #endif -FreeLocaleResult freelocale(LocaleType locale) { +FreeLocaleResult freelocale(LocaleType locale) FMT_LOCALE_THROW { LocaleMock::instance->freelocale(locale); return FreeLocaleResult(); } -double strtod_l(const char *nptr, char **endptr, LocaleType locale) { +double strtod_l(const char *nptr, char **endptr, LocaleType locale) FMT_LOCALE_THROW { return LocaleMock::instance->strtod_l(nptr, endptr, locale); } +#undef FMT_LOCALE_THROW + TEST(LocaleTest, LocaleMock) { ScopedMock mock; LocaleType locale = reinterpret_cast(11); From d1976cfb65d5f32f8a78129186deff5c52145acf Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Tue, 5 Jun 2018 11:56:11 +0300 Subject: [PATCH 14/15] Cleanups --- .travis.yml | 17 +++++++---------- appveyor.yml | 1 - include/fmt/format.h | 2 +- support/appveyor-build.py | 9 +-------- support/appveyor-test-upload.ps1 | 11 ----------- test/CMakeLists.txt | 2 +- 6 files changed, 10 insertions(+), 32 deletions(-) delete mode 120000 appveyor.yml delete mode 100644 support/appveyor-test-upload.ps1 diff --git a/.travis.yml b/.travis.yml index 1cdb9f5e59f4..ff042e9adc4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: - env: BUILD=Doc sudo: required # g++ 6 on Linux with C++14 - - env: CXX_COMPILER=g++-6 BUILD=Debug STANDARD=14 + - env: CXX=g++-6 BUILD=Debug STANDARD=14 compiler: gcc addons: apt: @@ -30,7 +30,7 @@ matrix: - ubuntu-toolchain-r-test packages: - g++-6 - - env: CXX_COMPILER=g++-6 BUILD=Release STANDARD=14 + - env: CXX=g++-6 BUILD=Release STANDARD=14 compiler: gcc addons: apt: @@ -47,7 +47,7 @@ matrix: compiler: clang os: osx # clang 6.0 on Linux with C++14 - - env: CXX_COMPILER=clang++-6.0 BUILD=Debug STANDARD=14 + - env: CXX=clang++-6.0 BUILD=Debug STANDARD=14 compiler: clang addons: apt: @@ -59,7 +59,7 @@ matrix: - llvm-toolchain-trusty - llvm-toolchain-trusty-6.0 # clang 4.0 on Linux with C++14 - - env: CXX_COMPILER=clang++-4.0 BUILD=Debug STANDARD=11 + - env: CXX=clang++-4.0 BUILD=Debug STANDARD=11 compiler: clang addons: apt: @@ -71,10 +71,10 @@ matrix: - llvm-toolchain-trusty - llvm-toolchain-trusty-4.0 # g++ 4.8 on Linux with C++11 - - env: CXX_COMPILER=g++-4.8 BUILD=Debug STANDARD=11 + - env: CXX=g++-4.8 BUILD=Debug STANDARD=11 compiler: gcc # g++ 4.4 on Linux with C++11 - - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=11 + - env: CXX=g++-4.4 BUILD=Debug STANDARD=11 compiler: gcc addons: apt: @@ -118,13 +118,10 @@ matrix: - tree ./libs allow_failures: # Errors - - env: CXX_COMPILER=g++-4.8 BUILD=Debug STANDARD=11 - compiler: gcc - - env: CXX_COMPILER=g++-4.4 BUILD=Debug STANDARD=11 + - env: CXX=g++-4.4 BUILD=Debug STANDARD=11 compiler: gcc before_script: - - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then export CXX=${CXX_COMPILER}; fi - if [[ "${BUILD}" != "Doc" ]]; then ${CXX} --version; fi script: diff --git a/appveyor.yml b/appveyor.yml deleted file mode 120000 index a053ea84d057..000000000000 --- a/appveyor.yml +++ /dev/null @@ -1 +0,0 @@ -support/appveyor.yml \ No newline at end of file diff --git a/include/fmt/format.h b/include/fmt/format.h index 018f1aafecc4..8c56b18bd3c9 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -294,7 +294,7 @@ class fp { significand_type f; int e; - static constexpr int significand_size = sizeof(significand_type) * char_size; + static FMT_CONSTEXPR_DECL const int significand_size = sizeof(significand_type) * char_size; fp(uint64_t f, int e): f(f), e(e) {} diff --git a/support/appveyor-build.py b/support/appveyor-build.py index d7b61562f49e..2cfcb03a414b 100644 --- a/support/appveyor-build.py +++ b/support/appveyor-build.py @@ -32,16 +32,9 @@ if platform == 'x64': generator += ' Win64' cmake_command.append('-G' + generator) - # build_command = ['msbuild', r'C:\projects\fmt\build\fmt.sln', '/m:4', - # r'/logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"'] build_command = ['cmake', '--build', '.', '--config', config, '--', '/m:4'] - test_command = ['ctest', '-C', config, '-T', 'Test'] - with open('DartConfiguration.tcl', 'w+') as file: - pass + test_command = ['ctest', '-C', config] check_call(cmake_command) check_call(build_command) check_call(test_command) - -# Upload test results -# check_call([r'../support/appveyor-test-upload.ps1', '-configuration', config, '-jobid', jobid]) diff --git a/support/appveyor-test-upload.ps1 b/support/appveyor-test-upload.ps1 deleted file mode 100644 index 0a2eb7afb8c1..000000000000 --- a/support/appveyor-test-upload.ps1 +++ /dev/null @@ -1,11 +0,0 @@ -param ( - [Parameter(Mandatory=$true)][string]$configuration, - [Parameter(Mandatory=$true)][string]$jobid -) - -$XSLInputElement = New-Object System.Xml.Xsl.XslCompiledTransform -$XslInputElement.Load("https://raw.githubusercontent.com/rpavlik/jenkins-ctest-plugin/master/ctest-to-junit.xsl") -$file = $(ls Testing\*\Test.xml) | Select -first 1 -$XSLInputElement.Transform((Resolve-Path $file), (Join-Path (Resolve-Path .) "ctest-to-junit-results.xml")) -$wc = New-Object 'System.Net.WebClient' -$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$jobid", (Resolve-Path .\ctest-to-junit-results.xml)) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 78e952e28ac6..5378c188915d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -145,7 +145,7 @@ if (FMT_PEDANTIC) no-windows-h-test PRIVATE ${PROJECT_SOURCE_DIR}/include) target_compile_definitions(no-windows-h-test PRIVATE FMT_USE_WINDOWS_H=0) if (FMT_PEDANTIC) - target_compile_options(no-windows-h-test ${PEDANTIC_COMPILE_FLAGS}) + target_compile_options(no-windows-h-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) endif () target_include_directories(no-windows-h-test SYSTEM PUBLIC gtest gmock) endif () From d79b096cc003c812f654d0e195ae3d29bdfe0f81 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Tue, 5 Jun 2018 12:21:26 +0300 Subject: [PATCH 15/15] Add C++11 support to ranges.h Re-enable ranges-test Fix a Visual Studio error about function not returning a value in printf.h Fix a bug in .travis.yml --- .ropeproject/config.py | 103 --------------------------------------- .ropeproject/globalnames | Bin 1713 -> 0 bytes .ropeproject/history | Bin 14 -> 0 bytes .ropeproject/objectdb | Bin 379 -> 0 bytes .travis.yml | 15 +++--- include/fmt/format.h | 2 +- include/fmt/printf.h | 2 + include/fmt/ranges.h | 55 ++++++++++++--------- test/CMakeLists.txt | 2 +- test/ranges-test.cc | 2 - 10 files changed, 45 insertions(+), 136 deletions(-) delete mode 100644 .ropeproject/config.py delete mode 100644 .ropeproject/globalnames delete mode 100644 .ropeproject/history delete mode 100644 .ropeproject/objectdb diff --git a/.ropeproject/config.py b/.ropeproject/config.py deleted file mode 100644 index 45e1fb46ca5c..000000000000 --- a/.ropeproject/config.py +++ /dev/null @@ -1,103 +0,0 @@ -# The default ``config.py`` -# flake8: noqa - - -def set_prefs(prefs): - """This function is called before opening the project""" - - # Specify which files and folders to ignore in the project. - # Changes to ignored resources are not added to the history and - # VCSs. Also they are not returned in `Project.get_files()`. - # Note that ``?`` and ``*`` match all characters but slashes. - # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' - # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' - # '.svn': matches 'pkg/.svn' and all of its children - # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' - # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' - prefs['ignored_resources'] = [ - '*.pyc', '*~', '.ropeproject', '.hg', '.svn', '_svn', - '.git', '.tox', '.env', 'env', 'venv', 'node_modules', - 'bower_components' - ] - - # Specifies which files should be considered python files. It is - # useful when you have scripts inside your project. Only files - # ending with ``.py`` are considered to be python files by - # default. - #prefs['python_files'] = ['*.py'] - - # Custom source folders: By default rope searches the project - # for finding source folders (folders that should be searched - # for finding modules). You can add paths to that list. Note - # that rope guesses project source folders correctly most of the - # time; use this if you have any problems. - # The folders should be relative to project root and use '/' for - # separating folders regardless of the platform rope is running on. - # 'src/my_source_folder' for instance. - #prefs.add('source_folders', 'src') - - # You can extend python path for looking up modules - #prefs.add('python_path', '~/python/') - - # Should rope save object information or not. - prefs['save_objectdb'] = True - prefs['compress_objectdb'] = False - - # If `True`, rope analyzes each module when it is being saved. - prefs['automatic_soa'] = True - # The depth of calls to follow in static object analysis - prefs['soa_followed_calls'] = 0 - - # If `False` when running modules or unit tests "dynamic object - # analysis" is turned off. This makes them much faster. - prefs['perform_doa'] = True - - # Rope can check the validity of its object DB when running. - prefs['validate_objectdb'] = True - - # How many undos to hold? - prefs['max_history_items'] = 32 - - # Shows whether to save history across sessions. - prefs['save_history'] = True - prefs['compress_history'] = False - - # Set the number spaces used for indenting. According to - # :PEP:`8`, it is best to use 4 spaces. Since most of rope's - # unit-tests use 4 spaces it is more reliable, too. - prefs['indent_size'] = 4 - - # Builtin and c-extension modules that are allowed to be imported - # and inspected by rope. - prefs['extension_modules'] = [] - - # Add all standard c-extensions to extension_modules list. - prefs['import_dynload_stdmods'] = True - - # If `True` modules with syntax errors are considered to be empty. - # The default value is `False`; When `False` syntax errors raise - # `rope.base.exceptions.ModuleSyntaxError` exception. - prefs['ignore_syntax_errors'] = False - - # If `True`, rope ignores unresolvable imports. Otherwise, they - # appear in the importing namespace. - prefs['ignore_bad_imports'] = False - - # If `True`, rope will insert new module imports as - # `from import ` by default. - prefs['prefer_module_from_imports'] = False - - # If `True`, rope will transform a comma list of imports into - # multiple separate import statements when organizing - # imports. - prefs['split_imports'] = False - - # If `True`, rope will sort imports alphabetically by module name - # instead of alphabetically by import statement, with from imports - # after normal imports. - prefs['sort_imports_alphabetically'] = False - - -def project_opened(project): - """This function is called after opening the project""" - # Do whatever you like here! diff --git a/.ropeproject/globalnames b/.ropeproject/globalnames deleted file mode 100644 index e4e1c7fb787349708ddb0aa854a5dd73c28e276e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1713 zcmYjRX?NT-6iw58FLYsF%VMA@Z7KUw+9tF>LP{E_SO%l9pFK)!Nl%i~3FmMQKb`06 zNiv^oz4hMvp7h`1zr2vCV+#ulr7N6Id}zdrnYt*3Wf)eqtvg-QN(e6SVRdTXvobY_ zkEr8fc%)OJVEL#zDW?>)jg<>6A5*90yh^&-i#V>%isha}6q7yM33WnjcSGH^WD}o6 z$@{KtwJrG+z^(gaoaNJq+#v2uppwtvIQVqKXVrPBGaTdNi3_Rd5}yO6bxZ4E%?0A~ zD7a$MgaTi{Vbg7sjrH}X!%UK>V zUzrQg$+i64ydl&({Jc81->IZZca8LVVXjxC0t&ncNWHka$-5|n;g`UHrXqXfm(>v| zv}}sRufRSV>#GDu;cUgPjrjEp2wELwZn?zp8!${#+vK85OZ+C(JTT-!cfwZ*RYOd- z+LGTI@!J_tnwZxjX*bRTRs0T$ZT5T62;so*Vp40%PlAz#oMFTQW`{!J_efn4(48-J zqNT!#(WKp_F_whiAMpp7IxGPXWZ$mguQY*|@Fz|AIv}|&c^UVI13=lGUYi>uzL`y~ zLEWMuZS!J6#kR!qEo5zU)(W7H)CFl!1QG=KxHCfH5r3Nje`r%6%1xEi)I`~!yXvyEZ1pyYVzGBvmj)-_ zQy?+}$(CdbLy_-;LnTCep_d`l(2`dG8e7r(z5~Br4t{_nnFoY<2;@na(@^Dm zjH{5P`9U3$#-4vfDWPgh9ZFsW|9w1Cd=1xV#$L`pVT_4lnvJMOu#U8%=a^TG7NH-Z zQ$N0+(W&AMLZGpWUo7vn19XX$<)$U?p31)P z-y_x;>a@nnJiW91%Q+rQdU{|gP)csO=Mp;-O>IqO3Q=7a_8(%xq@+gfswz_AN-fHK zD$g|pnYEliOT%VRcj|cy?m$rR`d4nDNx=5Wo+#X3= Z%n)7Ti?=FvP83V2oj-PvGDLzUd2O81iGhyi z@}2KLU!xWQUj{)C*S3laCE~JixzVp|9UIHa21hMMD?alp8(C4}i1eqbjK;C7Oi4^6 zmY7j&OIuSlsR%!$Z@=rzggA-5F>Y}h@u}yPwl2|G zoOigeEiOCE#P2Y((xfDDl@G>wi$%2BIYg}rr!=nl*c)A47KEGpfbo_uhHv*rS!PKO e=W*BL{t)}{m-Vp*cG=_6;mOB-?(iaN%YFbYxO0jC diff --git a/.travis.yml b/.travis.yml index ff042e9adc4d..f306cd627e16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: - env: BUILD=Doc sudo: required # g++ 6 on Linux with C++14 - - env: CXX=g++-6 BUILD=Debug STANDARD=14 + - env: COMPILER=g++-6 BUILD=Debug STANDARD=14 compiler: gcc addons: apt: @@ -30,7 +30,7 @@ matrix: - ubuntu-toolchain-r-test packages: - g++-6 - - env: CXX=g++-6 BUILD=Release STANDARD=14 + - env: COMPILER=g++-6 BUILD=Release STANDARD=14 compiler: gcc addons: apt: @@ -47,7 +47,7 @@ matrix: compiler: clang os: osx # clang 6.0 on Linux with C++14 - - env: CXX=clang++-6.0 BUILD=Debug STANDARD=14 + - env: COMPILER=clang++-6.0 BUILD=Debug STANDARD=14 compiler: clang addons: apt: @@ -59,7 +59,7 @@ matrix: - llvm-toolchain-trusty - llvm-toolchain-trusty-6.0 # clang 4.0 on Linux with C++14 - - env: CXX=clang++-4.0 BUILD=Debug STANDARD=11 + - env: COMPILER=clang++-4.0 BUILD=Debug STANDARD=11 compiler: clang addons: apt: @@ -71,10 +71,10 @@ matrix: - llvm-toolchain-trusty - llvm-toolchain-trusty-4.0 # g++ 4.8 on Linux with C++11 - - env: CXX=g++-4.8 BUILD=Debug STANDARD=11 + - env: COMPILER=g++-4.8 BUILD=Debug STANDARD=11 compiler: gcc # g++ 4.4 on Linux with C++11 - - env: CXX=g++-4.4 BUILD=Debug STANDARD=11 + - env: COMPILER=g++-4.4 BUILD=Debug STANDARD=11 compiler: gcc addons: apt: @@ -118,10 +118,11 @@ matrix: - tree ./libs allow_failures: # Errors - - env: CXX=g++-4.4 BUILD=Debug STANDARD=11 + - env: COMPILER=g++-4.4 BUILD=Debug STANDARD=11 compiler: gcc before_script: + - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then export CXX=${COMPILER}; fi - if [[ "${BUILD}" != "Doc" ]]; then ${CXX} --version; fi script: diff --git a/include/fmt/format.h b/include/fmt/format.h index 8c56b18bd3c9..8cb0c6a94e1a 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2919,7 +2919,7 @@ void basic_writer::write_double(T value, const format_specs &spec) { typedef back_insert_range> range; basic_writer w{range(buffer)}; w.write(hi); - unsigned digits = buffer.size(); + size_t digits = buffer.size(); w.write('.'); const unsigned max_digits = 18; while (digits++ < max_digits) { diff --git a/include/fmt/printf.h b/include/fmt/printf.h index fb69d5b18274..ea383783bcea 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -52,6 +52,7 @@ class printf_precision_handler: public function { typename std::enable_if::value, int>::type operator()(T) { FMT_THROW(format_error("precision is not integer")); + return 0; // Silence visual studio } }; @@ -193,6 +194,7 @@ class printf_width_handler: public function { typename std::enable_if::value, unsigned>::type operator()(T) { FMT_THROW(format_error("width is not integer")); + return 0; // Silence Visual Studio } }; } // namespace internal diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index cdb01ad67080..a235ecac433a 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -126,10 +126,9 @@ struct is_tuple_like { static FMT_CONSTEXPR_DECL const bool value = is_tuple_like_::value && !is_range_::value; }; -} // namespace internal // Check for integer_sequence -#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1910 +#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900 template using integer_sequence = std::integer_sequence; template @@ -179,21 +178,13 @@ void for_each(Tuple &&tup, F &&f) { template struct formatter::value>::type> { - - fmt::formatting_tuple formatting; - - template - FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin()) { - return formatting.parse(ctx); - } - - template - auto format(const TupleT &values, FormatContext &ctx) -> decltype(ctx.out()) { - auto out = ctx.out(); - std::size_t i = 0; - internal::copy(formatting.prefix, out); - internal::for_each(values, [&](const auto &v) { + typename std::enable_if::value>::type> { +private: + // C++11 generic lambda for format() + template + struct format_each { + template + void operator()(const T& v) { if (i > 0) { if (formatting.add_prepostfix_space) { *out++ = ' '; @@ -206,7 +197,28 @@ struct formatter& formatting; + std::size_t& i; + typename std::add_lvalue_reference().out())>::type out; + }; + +public: + formatting_tuple formatting; + + template + FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin()) { + return formatting.parse(ctx); + } + + template + auto format(const TupleT &values, FormatContext &ctx) -> decltype(ctx.out()) { + auto out = ctx.out(); + std::size_t i = 0; + internal::copy(formatting.prefix, out); + + internal::for_each(values, format_each{formatting, i, out}); if (formatting.add_prepostfix_space) { *out++ = ' '; } @@ -215,13 +227,12 @@ struct formatter -struct formatter< RangeT, Char, - typename std::enable_if::value>::type> { +struct formatter::value>::type> { - fmt::formatting_range formatting; + formatting_range formatting; template FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin()) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5378c188915d..1a8c900a605d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -93,7 +93,7 @@ add_fmt_test(printf-test) add_fmt_test(time-test) add_fmt_test(util-test mock-allocator.h) add_fmt_test(custom-formatter-test) -#add_fmt_test(ranges-test) +add_fmt_test(ranges-test) if (HAVE_OPEN) add_fmt_executable(posix-mock-test diff --git a/test/ranges-test.cc b/test/ranges-test.cc index efe4f4924aa2..1fab6ab43528 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -30,7 +30,6 @@ TEST(RangesTest, FormatVector2) { EXPECT_EQ("{{1, 2}, {3, 5}, {7, 11}}", ivf); } -#if FMT_USE_INTEGER_SEQUENCE TEST(RangesTest, FormatMap) { std::map simap{{"one", 1}, {"two", 2}}; EXPECT_EQ("{(one, 1), (two, 2)}", fmt::format("{}", simap)); @@ -87,4 +86,3 @@ TEST(RangesTest, FormatStruct) { #endif // (__cplusplus > 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG > // 201402L && _MSC_VER >= 1910) -#endif // FMT_USE_INTEGER_SEQUENCE