diff --git a/fmt/format.cc b/fmt/format.cc index f5481fbb..de969dc8 100644 --- a/fmt/format.cc +++ b/fmt/format.cc @@ -83,7 +83,10 @@ static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) { namespace fmt { -FMT_FUNC internal::RuntimeError::~RuntimeError() FMT_DTOR_NOEXCEPT {} +namespace internal { +FMT_FUNC RuntimeError::~RuntimeError() FMT_DTOR_NOEXCEPT {} +} // namespace internal + FMT_FUNC FormatError::~FormatError() FMT_DTOR_NOEXCEPT {} FMT_FUNC SystemError::~SystemError() FMT_DTOR_NOEXCEPT {} @@ -231,8 +234,9 @@ FMT_FUNC void SystemError::init( base = std::runtime_error(w.str()); } +namespace internal { template -int internal::CharTraits::format_float( +int CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, T value) { if (width == 0) { @@ -246,7 +250,7 @@ int internal::CharTraits::format_float( } template -int internal::CharTraits::format_float( +int CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, T value) { if (width == 0) { @@ -260,7 +264,7 @@ int internal::CharTraits::format_float( } template -const char internal::BasicData::DIGITS[] = +const char BasicData::DIGITS[] = "0001020304050607080910111213141516171819" "2021222324252627282930313233343536373839" "4041424344454647484950515253545556575859" @@ -279,12 +283,12 @@ const char internal::BasicData::DIGITS[] = factor * 1000000000 template -const uint32_t internal::BasicData::POWERS_OF_10_32[] = { +const uint32_t BasicData::POWERS_OF_10_32[] = { 0, FMT_POWERS_OF_10(1) }; template -const uint64_t internal::BasicData::POWERS_OF_10_64[] = { +const uint64_t BasicData::POWERS_OF_10_64[] = { 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(ULongLong(1000000000)), @@ -293,7 +297,7 @@ const uint64_t internal::BasicData::POWERS_OF_10_64[] = { ULongLong(1000000000) * ULongLong(1000000000) * 10 }; -FMT_FUNC void internal::report_unknown_type(char code, const char *type) { +FMT_FUNC void report_unknown_type(char code, const char *type) { (void)type; if (std::isprint(static_cast(code))) { FMT_THROW(FormatError( @@ -306,7 +310,7 @@ FMT_FUNC void internal::report_unknown_type(char code, const char *type) { #if FMT_USE_WINDOWS_H -FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) { +FMT_FUNC UTF8ToUTF16::UTF8ToUTF16(StringRef s) { static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16"; if (s.size() > INT_MAX) FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG)); @@ -323,14 +327,14 @@ FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) { buffer_[length] = 0; } -FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) { +FMT_FUNC UTF16ToUTF8::UTF16ToUTF8(WStringRef s) { if (int error_code = convert(s)) { FMT_THROW(WindowsError(error_code, "cannot convert string from UTF-16 to UTF-8")); } } -FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) { +FMT_FUNC int UTF16ToUTF8::convert(WStringRef s) { if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER; int s_size = static_cast(s.size()); @@ -346,6 +350,7 @@ FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) { buffer_[length] = 0; return 0; } +} // namespace internal FMT_FUNC void WindowsError::init( int err_code, CStringRef format_str, ArgList args) { @@ -356,7 +361,8 @@ FMT_FUNC void WindowsError::init( base = std::runtime_error(w.str()); } -FMT_FUNC void internal::format_windows_error( +namespace internal { +FMT_FUNC void format_windows_error( Writer &out, int error_code, StringRef message) FMT_NOEXCEPT { FMT_TRY { MemoryBuffer buffer; @@ -384,7 +390,7 @@ FMT_FUNC void internal::format_windows_error( } #endif // FMT_USE_WINDOWS_H - +} // namespace internal FMT_FUNC void format_system_error( Writer &out, int error_code, StringRef message) FMT_NOEXCEPT { FMT_TRY { @@ -404,38 +410,37 @@ FMT_FUNC void format_system_error( } FMT_CATCH(...) {} fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. } +} // namespace fmt template -void internal::FixedBuffer::grow(std::size_t) { +void fmt::internal::FixedBuffer::grow(std::size_t) { FMT_THROW(std::runtime_error("buffer overflow")); } -FMT_FUNC internal::Arg internal::FormatterBase::do_get_arg( +FMT_FUNC fmt::internal::Arg fmt::internal::FormatterBase::do_get_arg( unsigned arg_index, const char *&error) { - internal::Arg arg = args_[arg_index]; + fmt::internal::Arg arg = args_[arg_index]; switch (arg.type) { - case internal::Arg::NONE: + case fmt::internal::Arg::NONE: error = "argument index out of range"; break; - case internal::Arg::NAMED_ARG: - arg = *static_cast(arg.pointer); + case fmt::internal::Arg::NAMED_ARG: + arg = *static_cast(arg.pointer); break; default: /*nothing*/; } return arg; } - +namespace fmt { FMT_FUNC void report_system_error( - int error_code, fmt::StringRef message) FMT_NOEXCEPT { - // 'fmt::' is for bcc32. + int error_code, StringRef message) FMT_NOEXCEPT { report_error(format_system_error, error_code, message); } #if FMT_USE_WINDOWS_H FMT_FUNC void report_windows_error( - int error_code, fmt::StringRef message) FMT_NOEXCEPT { - // 'fmt::' is for bcc32. + int error_code, StringRef message) FMT_NOEXCEPT { report_error(internal::format_windows_error, error_code, message); } #endif @@ -463,28 +468,29 @@ FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args) { template struct internal::BasicData; // Explicit instantiations for char. +namespace internal { +template void FixedBuffer::grow(std::size_t); -template void internal::FixedBuffer::grow(std::size_t); - -template FMT_API int internal::CharTraits::format_float( +template FMT_API int CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, double value); -template FMT_API int internal::CharTraits::format_float( +template FMT_API int CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, long double value); // Explicit instantiations for wchar_t. -template void internal::FixedBuffer::grow(std::size_t); +template void FixedBuffer::grow(std::size_t); -template FMT_API int internal::CharTraits::format_float( +template FMT_API int CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, double value); -template FMT_API int internal::CharTraits::format_float( +template FMT_API int CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, long double value); +} //namespace internal #endif // FMT_HEADER_ONLY diff --git a/fmt/format.h b/fmt/format.h index fce1511b..37e298ed 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -130,6 +130,11 @@ typedef __int64 intmax_t; # define FMT_HAS_GXX_CXX11 0 #endif +#ifdef __BORLANDC__ +#pragma warn -8072 // disable "suspicious pointer arithmetic" warning on access of the digits array +#pragma warn -8004 // disable "assigned value that is never used" warning +#endif + #if defined(__INTEL_COMPILER) # define FMT_ICC_VERSION __INTEL_COMPILER #elif defined(__ICL) @@ -1328,6 +1333,7 @@ template struct LConvCheck { LConvCheck(int) {} }; +#ifndef __BORLANDC__ // Returns the thousands separator for the current locale. // We check if ``lconv`` contains ``thousands_sep`` because on Android // ``lconv`` is stubbed as an empty struct. @@ -1336,6 +1342,7 @@ inline StringRef thousands_sep( LConv *lc, LConvCheck = 0) { return lc->thousands_sep; } +#endif inline fmt::StringRef thousands_sep(...) { return ""; } @@ -2138,6 +2145,8 @@ class ArgFormatterBase : public ArgVisitor { // workaround MSVC two-phase lookup issue typedef internal::Arg Arg; + typedef Char CharType; + typedef BasicWriter WriterType; protected: BasicWriter &writer() { return writer_; } @@ -2182,8 +2191,8 @@ class ArgFormatterBase : public ArgVisitor { } if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0) FMT_THROW(FormatError("invalid format specifier for char")); - typedef typename BasicWriter::CharPtr CharPtr; - Char fill = internal::CharTraits::cast(spec_.fill()); + typedef typename WriterType::CharPtr CharPtr; + CharType fill = internal::CharTraits::cast(spec_.fill()); CharPtr out = CharPtr(); const unsigned CHAR_SIZE = 1; if (spec_.width_ > CHAR_SIZE) { @@ -2201,7 +2210,7 @@ class ArgFormatterBase : public ArgVisitor { } else { out = writer_.grow_buffer(CHAR_SIZE); } - *out = internal::CharTraits::cast(value); + *out = internal::CharTraits::cast(value); } void visit_cstring(const char *value) { @@ -2403,6 +2412,7 @@ inline uint64_t make_type(const T &arg) { return MakeValue< BasicFormatter >::type(arg); } +#ifndef __BORLANDC__ template struct ArgArray; @@ -2432,6 +2442,25 @@ struct ArgArray { template static Arg make(const T &value) { return MakeArg(value); } }; +#else +template +struct ArgArray { + typedef Value Type[N > 0 ? N : 1]; + + template + static Value make(const T & value) { +#ifdef __clang__ + Value result = MakeValue(value); + // Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang: + // https://github.com/fmtlib/fmt/issues/276 + (void)result.custom.format; + return result; +#else + return MakeValue(value); +#endif + } +}; +#endif #if FMT_USE_VARIADIC_TEMPLATES template @@ -4213,4 +4242,9 @@ operator"" _a(const wchar_t *s, std::size_t) { return {s}; } # define FMT_FUNC #endif +#ifdef __BORLANDC__ +#pragma warn .8072 // restore "suspicious pointer arithmetic" warning on access of the digits array +#pragma warn .8004 // restore "assigned value that is never used" warning +#endif + #endif // FMT_FORMAT_H_ diff --git a/fmt/posix.cc b/fmt/posix.cc index 356668c1..e7b57769 100644 --- a/fmt/posix.cc +++ b/fmt/posix.cc @@ -26,10 +26,13 @@ # endif # include # include - -# define O_CREAT _O_CREAT -# define O_TRUNC _O_TRUNC - +#include +# ifndef O_CREAT +# define O_CREAT _O_CREAT +# endif +# ifndef O_TRUNC +# define O_TRUNC _O_TRUNC +# endif # ifndef S_IRUSR # define S_IRUSR _S_IREAD # endif @@ -56,7 +59,7 @@ typedef int RWResult; // On Windows the count argument to read and write is unsigned, so convert // it from size_t preventing integer overflow. inline unsigned convert_rwcount(std::size_t count) { - return count <= UINT_MAX ? static_cast(count) : UINT_MAX; + return static_cast(std::min(count, UINT_MAX)); } #else // Return type of read and write functions. @@ -99,7 +102,7 @@ int fmt::BufferedFile::fileno() const { fmt::File::File(fmt::CStringRef path, int oflag) { int mode = S_IRUSR | S_IWUSR; -#if defined(_WIN32) && !defined(__MINGW32__) +#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__BORLANDC__) fd_ = -1; FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode)); #else diff --git a/fmt/posix.h b/fmt/posix.h index 88512de5..c3ce964a 100644 --- a/fmt/posix.h +++ b/fmt/posix.h @@ -46,6 +46,10 @@ # ifdef _WIN32 // Fix warnings about deprecated symbols. # define FMT_POSIX_CALL(call) ::_##call +# if defined(__BORLANDC__) && !defined(_dup2) +// for some reason the borland headers do define _dup but not _dup2 +# define _dup2 dup2 +# endif # else # define FMT_POSIX_CALL(call) ::call # endif diff --git a/fmt/printf.h b/fmt/printf.h index 46205a78..736d9d39 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -333,7 +333,7 @@ class PrintfFormatter : private internal::FormatterBase { \endrst */ explicit PrintfFormatter(const ArgList &al, BasicWriter &w) - : FormatterBase(al), writer_(w) {} + : internal::FormatterBase(al), writer_(w) {} /** Formats stored arguments and writes the output to the writer. */ void format(BasicCStringRef format_str); @@ -371,7 +371,7 @@ internal::Arg PrintfFormatter::get_arg(const Char *s, (void)s; const char *error = FMT_NULL; internal::Arg arg = arg_index == std::numeric_limits::max() ? - next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); + next_arg(error) : internal::FormatterBase::get_arg(arg_index - 1, error); if (error) FMT_THROW(FormatError(!*s ? "invalid format string" : error)); return arg; diff --git a/support/appveyor-build.py b/support/appveyor-build.py index 3b747f3c..a5dbbb3e 100755 --- a/support/appveyor-build.py +++ b/support/appveyor-build.py @@ -8,7 +8,7 @@ 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] +cmake_command = ['cmake', '-DFMT_PEDANTIC=ON', '-DCMAKE_BUILD_TYPE=' + config, '.'] if build == 'mingw': cmake_command.append('-GMinGW Makefiles') build_command = ['mingw32-make', '-j4']