aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dep/PackageList.txt2
-rw-r--r--dep/cppformat/CMakeLists.txt6
-rw-r--r--dep/cppformat/README.rst29
-rw-r--r--dep/cppformat/cppformat/format.cc (renamed from dep/cppformat/format.cc)118
-rw-r--r--dep/cppformat/cppformat/format.h (renamed from dep/cppformat/format.h)531
-rw-r--r--dep/cppformat/cppformat/posix.cc (renamed from dep/cppformat/posix.cc)4
-rw-r--r--dep/cppformat/cppformat/posix.h (renamed from dep/cppformat/posix.h)63
-rw-r--r--src/common/Utilities/StringFormat.h2
-rw-r--r--src/server/bnetserver/CMakeLists.txt2
-rw-r--r--src/server/worldserver/CMakeLists.txt2
-rw-r--r--src/tools/map_extractor/CMakeLists.txt2
-rw-r--r--src/tools/mmaps_generator/CMakeLists.txt2
12 files changed, 463 insertions, 300 deletions
diff --git a/dep/PackageList.txt b/dep/PackageList.txt
index 5ad9cef5982..7f10848aa0a 100644
--- a/dep/PackageList.txt
+++ b/dep/PackageList.txt
@@ -14,7 +14,7 @@ bzip2 (a freely available, patent free, high-quality data compressor)
cppformat (type safe format library)
https://github.com/cppformat/cppformat
- Version: 5c76d107cbaf5e851bd66b6c563e4fc7c90be7ad
+ Version: 5174b8ca281426af604b85fdf53be8a748b33f56
G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License)
http://g3d.sourceforge.net/
diff --git a/dep/cppformat/CMakeLists.txt b/dep/cppformat/CMakeLists.txt
index 3be3e5f6dbb..f2abb1b42d3 100644
--- a/dep/cppformat/CMakeLists.txt
+++ b/dep/cppformat/CMakeLists.txt
@@ -1,7 +1,7 @@
include(CheckCXXCompilerFlag)
include(CheckSymbolExists)
-set(FMT_SOURCES format.cc format.h)
+set(FMT_SOURCES cppformat/format.cc cppformat/format.h)
# Use variadic templates
add_definitions(-DFMT_VARIADIC_TEMPLATES=1)
@@ -20,10 +20,10 @@ endif ()
if (HAVE_OPEN)
add_definitions(-DFMT_USE_FILE_DESCRIPTORS=1)
- set(FMT_SOURCES ${FMT_SOURCES} posix.cc posix.h)
+ set(FMT_SOURCES ${FMT_SOURCES} cppformat/posix.cc cppformat/posix.h)
endif ()
-add_library(format STATIC ${FMT_SOURCES})
+add_library(cppformat STATIC ${FMT_SOURCES})
if (CMAKE_COMPILER_IS_GNUCXX)
set_target_properties(format PROPERTIES COMPILE_FLAGS
diff --git a/dep/cppformat/README.rst b/dep/cppformat/README.rst
index fb4399f0af4..e859f909466 100644
--- a/dep/cppformat/README.rst
+++ b/dep/cppformat/README.rst
@@ -28,9 +28,9 @@ Features
* Format API with `format string syntax
<http://cppformat.github.io/latest/syntax.html>`_
similar to the one used by `str.format
- <http://docs.python.org/2/library/stdtypes.html#str.format>`_ in Python.
+ <https://docs.python.org/2/library/stdtypes.html#str.format>`_ in Python.
* Safe `printf implementation
- <http://cppformat.github.io/latest/reference.html#printf-formatting-functions>`_
+ <http://cppformat.github.io/latest/api.html#printf-formatting-functions>`_
including the POSIX extension for positional arguments.
* Support for user-defined types.
* High speed: performance of the format API is close to that of
@@ -103,10 +103,10 @@ An object of any user-defined type for which there is an overloaded
// s == "The date is 2012-12-9"
You can use the `FMT_VARIADIC
-<http://cppformat.github.io/latest/reference.html#utilities>`_
+<http://cppformat.github.io/latest/api.html#utilities>`_
macro to create your own functions similar to `format
-<http://cppformat.github.io/latest/reference.html#format>`_ and
-`print <http://cppformat.github.io/latest/reference.html#print>`_
+<http://cppformat.github.io/latest/api.html#format>`_ and
+`print <http://cppformat.github.io/latest/api.html#print>`_
which take arbitrary arguments:
.. code:: c++
@@ -132,13 +132,17 @@ Projects using this library
* `AMPL/MP <https://github.com/ampl/mp>`_:
An open-source library for mathematical programming
-* `HarpyWar/pvpgn <https://github.com/HarpyWar/pvpgn>`_:
+* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
Player vs Player Gaming Network with tweaks
-* `KBEngine <http://www.kbengine.org/>`_: An open-source MMOG server engine
+* `KBEngine <http://kbengine.org/>`_: An open-source MMOG server engine
+
+* `Keypirinha <http://keypirinha.com/>`_: A semantic launcher for Windows
* `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
+* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to generate randomized datasets
+
* `PenUltima Online (POL) <http://www.polserver.com/>`_:
An MMO server, compatible with most Ultima Online clients
@@ -148,7 +152,7 @@ Projects using this library
* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster proxy
-* `Saddy <https://code.google.com/p/saddy/>`_:
+* `Saddy <https://github.com/mamontov-cpp/saddy-graphics-engine-2d>`_:
Small crossplatform 2D graphic engine
* `Salesforce Analytics Cloud <http://www.salesforce.com/analytics-cloud/overview/>`_:
@@ -188,7 +192,7 @@ doesn't support user-defined types. Printf also has safety issues although
they are mostly solved with `__attribute__ ((format (printf, ...))
<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
There is a POSIX extension that adds positional arguments required for
-`i18n <http://en.wikipedia.org/wiki/Internationalization_and_localization>`_
+`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
to printf but it is not a part of C99 and may not be available on some
platforms.
@@ -376,18 +380,13 @@ C++ Format is distributed under the BSD `license
The `Format String Syntax
<http://cppformat.github.io/latest/syntax.html>`_
section in the documentation is based on the one from Python `string module
-documentation <http://docs.python.org/3/library/string.html#module-string>`_
+documentation <https://docs.python.org/3/library/string.html#module-string>`_
adapted for the current library. For this reason the documentation is
distributed under the Python Software Foundation license available in
`doc/python-license.txt
<https://raw.github.com/cppformat/cppformat/master/doc/python-license.txt>`_.
It only applies if you distribute the documentation of C++ Format.
-Links
------
-
-`API changes/compatibility report <http://upstream-tracker.org/versions/cppformat.html>`_
-
Acknowledgments
---------------
diff --git a/dep/cppformat/format.cc b/dep/cppformat/cppformat/format.cc
index 1970d53c500..daccd68f1da 100644
--- a/dep/cppformat/format.cc
+++ b/dep/cppformat/cppformat/format.cc
@@ -207,10 +207,15 @@ void format_error_code(fmt::Writer &out, int error_code,
out.clear();
static const char SEP[] = ": ";
static const char ERROR_STR[] = "error ";
- fmt::internal::IntTraits<int>::MainType ec_value = error_code;
// Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
- error_code_size += fmt::internal::count_digits(ec_value);
+ typedef fmt::internal::IntTraits<int>::MainType MainType;
+ MainType abs_value = static_cast<MainType>(error_code);
+ if (internal::is_negative(error_code)) {
+ abs_value = 0 - abs_value;
+ ++error_code_size;
+ }
+ error_code_size += fmt::internal::count_digits(abs_value);
if (message.size() <= fmt::internal::INLINE_BUFFER_SIZE - error_code_size)
out << message << SEP;
out << ERROR_STR << error_code;
@@ -252,7 +257,7 @@ class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> {
template <typename T>
unsigned visit_any_int(T value) {
typedef typename fmt::internal::IntTraits<T>::MainType UnsignedType;
- UnsignedType width = value;
+ UnsignedType width = static_cast<UnsignedType>(value);
if (fmt::internal::is_negative(value)) {
spec_.align_ = fmt::ALIGN_LEFT;
width = 0 - width;
@@ -278,8 +283,21 @@ class PrecisionHandler :
}
};
-// Converts an integer argument to an integral type T for printf.
+template <typename T, typename U>
+struct is_same {
+ enum { value = 0 };
+};
+
template <typename T>
+struct is_same<T, T> {
+ enum { value = 1 };
+};
+
+// An argument visitor that converts an integer argument to T for printf,
+// if T is an integral type. If T is void, the argument is converted to
+// corresponding signed or unsigned type depending on the type specifier:
+// 'd' and 'i' - signed, other - unsigned)
+template <typename T = void>
class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> {
private:
fmt::internal::Arg &arg_;
@@ -300,21 +318,25 @@ class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> {
void visit_any_int(U value) {
bool is_signed = type_ == 'd' || type_ == 'i';
using fmt::internal::Arg;
- if (sizeof(T) <= sizeof(int)) {
+ typedef typename fmt::internal::Conditional<
+ is_same<T, void>::value, U, T>::type TargetType;
+ if (sizeof(TargetType) <= sizeof(int)) {
// Extra casts are used to silence warnings.
if (is_signed) {
arg_.type = Arg::INT;
- arg_.int_value = static_cast<int>(static_cast<T>(value));
+ arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
} else {
arg_.type = Arg::UINT;
- arg_.uint_value = static_cast<unsigned>(
- static_cast<typename fmt::internal::MakeUnsigned<T>::Type>(value));
+ typedef typename fmt::internal::MakeUnsigned<TargetType>::Type Unsigned;
+ arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
}
} else {
if (is_signed) {
arg_.type = Arg::LONG_LONG;
- arg_.long_long_value =
- static_cast<typename fmt::internal::MakeUnsigned<U>::Type>(value);
+ // glibc's printf doesn't sign extend arguments of smaller types:
+ // std::printf("%lld", -42); // prints "4294967254"
+ // but we don't have to do the same because it's a UB.
+ arg_.long_long_value = static_cast<fmt::LongLong>(value);
} else {
arg_.type = Arg::ULONG_LONG;
arg_.ulong_long_value =
@@ -340,6 +362,21 @@ class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> {
arg_.int_value = static_cast<char>(value);
}
};
+
+// Write the content of w to os.
+void write(std::ostream &os, fmt::Writer &w) {
+ const char *data = w.data();
+ typedef internal::MakeUnsigned<std::streamsize>::Type UnsignedStreamSize;
+ UnsignedStreamSize size = w.size();
+ UnsignedStreamSize max_size =
+ internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
+ do {
+ UnsignedStreamSize n = size <= max_size ? size : max_size;
+ os.write(data, static_cast<std::streamsize>(n));
+ data += n;
+ size -= n;
+ } while (size != 0);
+}
} // namespace
namespace internal {
@@ -551,27 +588,25 @@ FMT_FUNC void fmt::WindowsError::init(
FMT_FUNC void fmt::internal::format_windows_error(
fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT {
- class String {
- private:
- LPWSTR str_;
-
- public:
- String() : str_() {}
- ~String() { LocalFree(str_); }
- LPWSTR *ptr() { return &str_; }
- LPCWSTR c_str() const { return str_; }
- };
FMT_TRY {
- String system_message;
- if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
- error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- reinterpret_cast<LPWSTR>(system_message.ptr()), 0, 0)) {
- UTF16ToUTF8 utf8_message;
- if (utf8_message.convert(system_message.c_str()) == ERROR_SUCCESS) {
- out << message << ": " << utf8_message;
- return;
+ MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
+ buffer.resize(INLINE_BUFFER_SIZE);
+ for (;;) {
+ wchar_t *system_message = &buffer[0];
+ int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ 0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ system_message, static_cast<uint32_t>(buffer.size()), 0);
+ if (result != 0) {
+ UTF16ToUTF8 utf8_message;
+ if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
+ out << message << ": " << utf8_message;
+ return;
+ }
+ break;
}
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ break; // Can't get error message, report error code instead.
+ buffer.resize(buffer.size() * 2);
}
} FMT_CATCH(...) {}
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
@@ -616,7 +651,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
return;
case internal::Arg::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
- map_.insert(Pair(named_arg->name, *named_arg));
+ map_.push_back(Pair(named_arg->name, *named_arg));
break;
default:
/*nothing*/;
@@ -628,7 +663,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
internal::Arg::Type arg_type = args.type(i);
if (arg_type == internal::Arg::NAMED_ARG) {
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
- map_.insert(Pair(named_arg->name, *named_arg));
+ map_.push_back(Pair(named_arg->name, *named_arg));
}
}
for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
@@ -637,7 +672,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
return;
case internal::Arg::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
- map_.insert(Pair(named_arg->name, *named_arg));
+ map_.push_back(Pair(named_arg->name, *named_arg));
break;
default:
/*nothing*/;
@@ -659,6 +694,7 @@ FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
break;
case Arg::NAMED_ARG:
arg = *static_cast<const internal::Arg*>(arg.pointer);
+ break;
default:
/*nothing*/;
}
@@ -763,7 +799,7 @@ void fmt::internal::PrintfFormatter<Char>::format(
if (*s == '.') {
++s;
if ('0' <= *s && *s <= '9') {
- spec.precision_ = parse_nonnegative_int(s);
+ spec.precision_ = static_cast<int>(parse_nonnegative_int(s));
} else if (*s == '*') {
++s;
spec.precision_ = PrecisionHandler().visit(get_arg(s));
@@ -772,7 +808,7 @@ void fmt::internal::PrintfFormatter<Char>::format(
Arg arg = get_arg(s, arg_index);
if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg))
- spec.flags_ &= ~HASH_FLAG;
+ spec.flags_ &= ~to_unsigned<int>(HASH_FLAG);
if (spec.fill_ == '0') {
if (arg.type <= Arg::LAST_NUMERIC_TYPE)
spec.align_ = ALIGN_NUMERIC;
@@ -809,7 +845,7 @@ void fmt::internal::PrintfFormatter<Char>::format(
break;
default:
--s;
- ArgConverter<int>(arg, *s).visit(arg);
+ ArgConverter<void>(arg, *s).visit(arg);
}
// Parse type.
@@ -861,10 +897,11 @@ FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) {
print(stdout, format_str, args);
}
-FMT_FUNC void fmt::print(std::ostream &os, CStringRef format_str, ArgList args) {
+FMT_FUNC void fmt::print(std::ostream &os, CStringRef format_str,
+ ArgList args) {
MemoryWriter w;
w.write(format_str, args);
- os.write(w.data(), w.size());
+ write(os, w);
}
FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) {
@@ -882,6 +919,13 @@ FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
}
+FMT_FUNC int fmt::fprintf(std::ostream &os, CStringRef format, ArgList args) {
+ MemoryWriter w;
+ printf(w, format, args);
+ write(os, w);
+ return static_cast<int>(w.size());
+}
+
#ifndef FMT_HEADER_ONLY
template struct fmt::internal::BasicData<void>;
diff --git a/dep/cppformat/format.h b/dep/cppformat/cppformat/format.h
index a98a166091b..08bb9b5d9e8 100644
--- a/dep/cppformat/format.h
+++ b/dep/cppformat/cppformat/format.h
@@ -28,14 +28,6 @@
#ifndef FMT_FORMAT_H_
#define FMT_FORMAT_H_
-#if defined _MSC_VER && _MSC_VER <= 1500
-typedef unsigned int uint32_t;
-typedef unsigned long long uint64_t;
-typedef long long intmax_t;
-#else
-#include <stdint.h>
-#endif
-
#include <cassert>
#include <cmath>
#include <cstdio>
@@ -44,7 +36,8 @@ typedef long long intmax_t;
#include <memory>
#include <stdexcept>
#include <string>
-#include <map>
+#include <vector>
+#include <utility>
#ifndef FMT_USE_IOSTREAMS
# define FMT_USE_IOSTREAMS 1
@@ -64,40 +57,23 @@ typedef long long intmax_t;
# include <iterator>
#endif
-#ifdef _MSC_VER
-# include <intrin.h> // _BitScanReverse, _BitScanReverse64
-
-namespace fmt {
-namespace internal {
-# pragma intrinsic(_BitScanReverse)
-inline uint32_t clz(uint32_t x) {
- unsigned long r = 0;
- _BitScanReverse(&r, x);
- return 31 - r;
-}
-# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
-
-# ifdef _WIN64
-# pragma intrinsic(_BitScanReverse64)
-# endif
-
-inline uint32_t clzll(uint64_t x) {
- unsigned long r = 0;
-# ifdef _WIN64
- _BitScanReverse64(&r, x);
-# else
- // Scan the high 32 bits.
- if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
- return 63 - (r + 32);
+#if defined(_MSC_VER) && _MSC_VER <= 1500
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+typedef __int64 intmax_t;
+#else
+#include <stdint.h>
+#endif
- // Scan the low 32 bits.
- _BitScanReverse(&r, static_cast<uint32_t>(x));
+#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
+# ifdef FMT_EXPORT
+# define FMT_API __declspec(dllexport)
+# elif defined(FMT_SHARED)
+# define FMT_API __declspec(dllimport)
# endif
- return 63 - r;
-}
-# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
-}
-}
+#endif
+#ifndef FMT_API
+# define FMT_API
#endif
#ifdef __GNUC__
@@ -174,21 +150,6 @@ inline uint32_t clzll(uint64_t x) {
# include <utility> // for std::move
#endif
-// Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature).
-#ifndef FMT_USE_NOEXCEPT
-# define FMT_USE_NOEXCEPT 0
-#endif
-
-#ifndef FMT_NOEXCEPT
-# if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
- (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
- _MSC_VER >= 1900
-# define FMT_NOEXCEPT noexcept
-# else
-# define FMT_NOEXCEPT throw()
-# endif
-#endif
-
// Check if exceptions are disabled.
#if defined(__GNUC__) && !defined(__EXCEPTIONS)
# define FMT_EXCEPTIONS 0
@@ -208,6 +169,25 @@ inline uint32_t clzll(uint64_t x) {
# endif
#endif
+// Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature).
+#ifndef FMT_USE_NOEXCEPT
+# define FMT_USE_NOEXCEPT 0
+#endif
+
+#ifndef FMT_NOEXCEPT
+# if FMT_EXCEPTIONS
+# if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
+ (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
+ _MSC_VER >= 1900
+# define FMT_NOEXCEPT noexcept
+# else
+# define FMT_NOEXCEPT throw()
+# endif
+# else
+# define FMT_NOEXCEPT
+# endif
+#endif
+
// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
#ifndef FMT_USE_DELETED_FUNCTIONS
@@ -241,6 +221,67 @@ inline uint32_t clzll(uint64_t x) {
# define FMT_ASSERT(condition, message) assert((condition) && message)
#endif
+
+#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
+# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
+#endif
+
+#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
+# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
+#endif
+
+// Some compilers masquerade as both MSVC and GCC-likes or
+// otherwise support __builtin_clz and __builtin_clzll, so
+// only define FMT_BUILTIN_CLZ using the MSVC intrinsics
+// if the clz and clzll builtins are not available.
+#if defined(_MSC_VER) && !defined(FMT_BUILTIN_CLZLL)
+# include <intrin.h> // _BitScanReverse, _BitScanReverse64
+
+namespace fmt {
+namespace internal {
+# pragma intrinsic(_BitScanReverse)
+inline uint32_t clz(uint32_t x) {
+ unsigned long r = 0;
+ _BitScanReverse(&r, x);
+
+ assert(x != 0);
+ // Static analysis complains about using uninitialized data
+ // "r", but the only way that can happen is if "x" is 0,
+ // which the callers guarantee to not happen.
+# pragma warning(suppress: 6102)
+ return 31 - r;
+}
+# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
+
+# ifdef _WIN64
+# pragma intrinsic(_BitScanReverse64)
+# endif
+
+inline uint32_t clzll(uint64_t x) {
+ unsigned long r = 0;
+# ifdef _WIN64
+ _BitScanReverse64(&r, x);
+# else
+ // Scan the high 32 bits.
+ if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
+ return 63 - (r + 32);
+
+ // Scan the low 32 bits.
+ _BitScanReverse(&r, static_cast<uint32_t>(x));
+# endif
+
+ assert(x != 0);
+ // Static analysis complains about using uninitialized data
+ // "r", but the only way that can happen is if "x" is 0,
+ // which the callers guarantee to not happen.
+# pragma warning(suppress: 6102)
+ return 63 - r;
+}
+# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
+}
+}
+#endif
+
namespace fmt {
namespace internal {
struct DummyInt {
@@ -396,7 +437,7 @@ class BasicStringRef {
return std::basic_string<Char>(data_, size_);
}
- /** Returns the pointer to a C string. */
+ /** Returns a pointer to the string data. */
const Char *data() const { return data_; }
/** Returns the string size. */
@@ -492,6 +533,29 @@ class FormatError : public std::runtime_error {
};
namespace internal {
+
+// MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
+template <typename T>
+struct MakeUnsigned { typedef T Type; };
+
+#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
+ template <> \
+ struct MakeUnsigned<T> { typedef U Type; }
+
+FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
+FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
+FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
+FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
+FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
+FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
+
+// Casts nonnegative integer to unsigned.
+template <typename Int>
+inline typename MakeUnsigned<Int>::Type to_unsigned(Int value) {
+ FMT_ASSERT(value >= 0, "negative value");
+ return static_cast<typename MakeUnsigned<Int>::Type>(value);
+}
+
// The number of characters to store in the MemoryBuffer object itself
// to avoid dynamic memory allocation.
enum { INLINE_BUFFER_SIZE = 500 };
@@ -581,8 +645,7 @@ class Buffer {
template <typename T>
template <typename U>
void Buffer<T>::append(const U *begin, const U *end) {
- assert(begin <= end);
- std::size_t new_size = size_ + (end - begin);
+ std::size_t new_size = size_ + internal::to_unsigned(end - begin);
if (new_size > capacity_)
grow(new_size);
std::uninitialized_copy(begin, end,
@@ -592,8 +655,8 @@ void Buffer<T>::append(const U *begin, const U *end) {
namespace internal {
-// A memory buffer for POD types with the first SIZE elements stored in
-// the object itself.
+// A memory buffer for trivially copyable/constructible types with the first SIZE
+// elements stored in the object itself.
template <typename T, std::size_t SIZE, typename Allocator = std::allocator<T> >
class MemoryBuffer : private Allocator, public Buffer<T> {
private:
@@ -676,7 +739,7 @@ class FixedBuffer : public fmt::Buffer<Char> {
FixedBuffer(Char *array, std::size_t size) : fmt::Buffer<Char>(array, size) {}
protected:
- void grow(std::size_t size);
+ FMT_API void grow(std::size_t size);
};
template <typename Char>
@@ -704,7 +767,7 @@ class CharTraits<char> : public BasicCharTraits<char> {
// Formats a floating-point number.
template <typename T>
- static int format_float(char *buffer, std::size_t size,
+ FMT_API static int format_float(char *buffer, std::size_t size,
const char *format, unsigned width, int precision, T value);
};
@@ -715,7 +778,7 @@ class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
static wchar_t convert(wchar_t value) { return value; }
template <typename T>
- static int format_float(wchar_t *buffer, std::size_t size,
+ FMT_API static int format_float(wchar_t *buffer, std::size_t size,
const wchar_t *format, unsigned width, int precision, T value);
};
@@ -754,27 +817,12 @@ struct IntTraits {
TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
};
-// MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
-template <typename T>
-struct MakeUnsigned { typedef T Type; };
-
-#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
- template <> \
- struct MakeUnsigned<T> { typedef U Type; }
-
-FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
-FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
-FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
-FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
-FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
-FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
-
-void report_unknown_type(char code, const char *type);
+FMT_API void report_unknown_type(char code, const char *type);
// Static data is placed in this class template to allow header-only
// configuration.
template <typename T = void>
-struct BasicData {
+struct FMT_API BasicData {
static const uint32_t POWERS_OF_10_32[];
static const uint64_t POWERS_OF_10_64[];
static const char DIGITS[];
@@ -782,22 +830,14 @@ struct BasicData {
typedef BasicData<> Data;
-#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
-# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
-#endif
-
-#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
-# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
-#endif
-
#ifdef FMT_BUILTIN_CLZLL
// Returns the number of decimal digits in n. Leading zeros are not counted
// except for n == 0 in which case count_digits returns 1.
inline unsigned count_digits(uint64_t n) {
// Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
// and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
- unsigned t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
- return t - (n < Data::POWERS_OF_10_64[t]) + 1;
+ int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
+ return to_unsigned(t) - (n < Data::POWERS_OF_10_64[t]) + 1;
}
#else
// Fallback version of count_digits used when __builtin_clz is not available.
@@ -820,8 +860,8 @@ inline unsigned count_digits(uint64_t n) {
#ifdef FMT_BUILTIN_CLZ
// Optional version of count_digits for better performance on 32-bit platforms.
inline unsigned count_digits(uint32_t n) {
- uint32_t t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
- return t - (n < Data::POWERS_OF_10_32[t]) + 1;
+ int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
+ return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1;
}
#endif
@@ -863,7 +903,7 @@ class UTF8ToUTF16 {
MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer_;
public:
- explicit UTF8ToUTF16(StringRef s);
+ FMT_API explicit UTF8ToUTF16(StringRef s);
operator WStringRef() const { return WStringRef(&buffer_[0], size()); }
size_t size() const { return buffer_.size() - 1; }
const wchar_t *c_str() const { return &buffer_[0]; }
@@ -878,7 +918,7 @@ class UTF16ToUTF8 {
public:
UTF16ToUTF8() {}
- explicit UTF16ToUTF8(WStringRef s);
+ FMT_API explicit UTF16ToUTF8(WStringRef s);
operator StringRef() const { return StringRef(&buffer_[0], size()); }
size_t size() const { return buffer_.size() - 1; }
const char *c_str() const { return &buffer_[0]; }
@@ -887,15 +927,15 @@ class UTF16ToUTF8 {
// Performs conversion returning a system error code instead of
// throwing exception on conversion error. This method may still throw
// in case of memory allocation error.
- int convert(WStringRef s);
+ FMT_API int convert(WStringRef s);
};
-void format_windows_error(fmt::Writer &out, int error_code,
- fmt::StringRef message) FMT_NOEXCEPT;
+FMT_API void format_windows_error(fmt::Writer &out, int error_code,
+ fmt::StringRef message) FMT_NOEXCEPT;
#endif
-void format_system_error(fmt::Writer &out, int error_code,
- fmt::StringRef message) FMT_NOEXCEPT;
+FMT_API void format_system_error(fmt::Writer &out, int error_code,
+ fmt::StringRef message) FMT_NOEXCEPT;
// A formatting argument value.
struct Value {
@@ -938,8 +978,8 @@ struct Value {
};
};
-// A formatting argument. It is a POD type to allow storage in
-// internal::MemoryBuffer.
+// A formatting argument. It is a trivially copyable/constructible type to
+// allow storage in internal::MemoryBuffer.
struct Arg : Value {
Type type;
};
@@ -976,6 +1016,7 @@ template <typename T>
T &get();
struct DummyStream : std::ostream {
+ DummyStream(); // Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
void operator<<(Null<>);
};
@@ -1199,17 +1240,27 @@ class MakeValue : public Arg {
static uint64_t type(const NamedArg<Char_> &) { return Arg::NAMED_ARG; }
};
+template <typename Formatter>
+class MakeArg : public Arg {
+public:
+ MakeArg() {
+ type = Arg::NONE;
+ }
+
+ template <typename T>
+ MakeArg(const T &value)
+ : Arg(MakeValue<Formatter>(value)) {
+ type = static_cast<Arg::Type>(MakeValue<Formatter>::type(value));
+ }
+};
+
template <typename Char>
struct NamedArg : Arg {
BasicStringRef<Char> name;
- typedef internal::MakeValue< BasicFormatter<Char> > MakeValue;
-
template <typename T>
NamedArg(BasicStringRef<Char> argname, const T &value)
- : Arg(MakeValue(value)), name(argname) {
- type = static_cast<Arg::Type>(MakeValue::type(value));
- }
+ : Arg(MakeArg< BasicFormatter<Char> >(value)), name(argname) {}
};
#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
@@ -1631,17 +1682,22 @@ namespace internal {
template <typename Char>
class ArgMap {
private:
- typedef std::map<fmt::BasicStringRef<Char>, internal::Arg> MapType;
+ typedef std::vector<std::pair<fmt::BasicStringRef<Char>, internal::Arg> > MapType;
typedef typename MapType::value_type Pair;
MapType map_;
public:
- void init(const ArgList &args);
+ FMT_API void init(const ArgList &args);
const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const {
- typename MapType::const_iterator it = map_.find(name);
- return it != map_.end() ? &it->second : 0;
+ // The list is unsorted, so just return the first matching name.
+ for (typename MapType::const_iterator it = map_.begin(), end = map_.end();
+ it != end; ++it) {
+ if (it->first == name)
+ return &it->second;
+ }
+ return 0;
}
};
@@ -1767,7 +1823,7 @@ class FormatterBase {
int next_arg_index_;
// Returns the argument with specified index.
- Arg do_get_arg(unsigned arg_index, const char *&error);
+ FMT_API Arg do_get_arg(unsigned arg_index, const char *&error);
protected:
const ArgList &args() const { return args_; }
@@ -1780,7 +1836,7 @@ class FormatterBase {
// Returns the next argument.
Arg next_arg(const char *&error) {
if (next_arg_index_ >= 0)
- return do_get_arg(next_arg_index_++, error);
+ return do_get_arg(internal::to_unsigned(next_arg_index_++), error);
error = "cannot switch from manual to automatic argument indexing";
return Arg();
}
@@ -1803,7 +1859,7 @@ class FormatterBase {
template <typename Char>
void write(BasicWriter<Char> &w, const Char *start, const Char *end) {
if (start != end)
- w << BasicStringRef<Char>(start, end - start);
+ w << BasicStringRef<Char>(start, internal::to_unsigned(end - start));
}
};
@@ -1823,14 +1879,16 @@ class PrintfFormatter : private FormatterBase {
public:
explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {}
- void format(BasicWriter<Char> &writer, BasicCStringRef<Char> format_str);
+ FMT_API void format(BasicWriter<Char> &writer,
+ BasicCStringRef<Char> format_str);
};
} // namespace internal
-// A formatter.
+/** This template formats data and writes the output to a writer. */
template <typename CharType>
class BasicFormatter : private internal::FormatterBase {
public:
+ /** The character type for the output. */
typedef CharType Char;
private:
@@ -1852,13 +1910,23 @@ class BasicFormatter : private internal::FormatterBase {
internal::Arg parse_arg_name(const Char *&s);
public:
+ /**
+ \rst
+ Constructs a ``BasicFormatter`` object. References to the arguments and
+ the writer are stored in the formatter object so make sure they have
+ appropriate lifetimes.
+ \endrst
+ */
BasicFormatter(const ArgList &args, BasicWriter<Char> &w)
: internal::FormatterBase(args), writer_(w) {}
+ /** Returns a reference to the writer associated with this formatter. */
BasicWriter<Char> &writer() { return writer_; }
+ /** Formats stored arguments and writes the output to the writer. */
void format(BasicCStringRef<Char> format_str);
+ // Formats a single argument and advances format_str, a format string pointer.
const Char *format(const Char *&format_str, const internal::Arg &arg);
};
@@ -1889,16 +1957,29 @@ inline uint64_t make_type(const T &arg) {
return MakeValue< BasicFormatter<char> >::type(arg);
}
+template <unsigned N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
+struct ArgArray;
+
+template <unsigned N>
+struct ArgArray<N, true/*IsPacked*/> {
+ typedef Value Type[N > 0 ? N : 1];
+
+ template <typename Formatter, typename T>
+ static Value make(const T &value) {
+ Value result = MakeValue<Formatter>(value);
+ // Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang:
+ // https://github.com/cppformat/cppformat/issues/276
+ (void)result.custom.format;
+ return result;
+ }
+};
+
template <unsigned N>
-struct ArgArray {
- // Computes the argument array size by adding 1 to N, which is the number of
- // arguments, if N is zero, because array of zero size is invalid, or if N
- // is greater than ArgList::MAX_PACKED_ARGS to accommodate for an extra
- // argument that marks the end of the list.
- enum { SIZE = N + (N == 0 || N >= ArgList::MAX_PACKED_ARGS ? 1 : 0) };
-
- typedef typename Conditional<
- (N < ArgList::MAX_PACKED_ARGS), Value, Arg>::type Type[SIZE];
+struct ArgArray<N, false/*IsPacked*/> {
+ typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE
+
+ template <typename Formatter, typename T>
+ static Arg make(const T &value) { return MakeArg<Formatter>(value); }
};
#if FMT_USE_VARIADIC_TEMPLATES
@@ -1907,47 +1988,6 @@ inline uint64_t make_type(const Arg &first, const Args & ... tail) {
return make_type(first) | (make_type(tail...) << 4);
}
-inline void do_set_types(Arg *) {}
-
-template <typename T, typename... Args>
-inline void do_set_types(Arg *args, const T &arg, const Args & ... tail) {
- args->type = static_cast<Arg::Type>(
- MakeValue< BasicFormatter<char> >::type(arg));
- do_set_types(args + 1, tail...);
-}
-
-template <typename... Args>
-inline void set_types(Arg *array, const Args & ... args) {
- if (check(sizeof...(Args) > ArgList::MAX_PACKED_ARGS))
- do_set_types(array, args...);
- array[sizeof...(Args)].type = Arg::NONE;
-}
-
-template <typename... Args>
-inline void set_types(Value *, const Args & ...) {
- // Do nothing as types are passed separately from values.
-}
-
-template <typename Formatter, typename Value>
-inline void store_args(Value *) {}
-
-template <typename Formatter, typename Arg, typename T, typename... Args>
-inline void store_args(Arg *args, const T &arg, const Args & ... tail) {
- // Assign only the Value subobject of Arg and don't overwrite type (if any)
- // that is assigned by set_types.
- Value &value = *args;
- value = MakeValue<Formatter>(arg);
- store_args<Formatter>(args + 1, tail...);
-}
-
-template <typename Formatter, typename... Args>
-ArgList make_arg_list(typename ArgArray<sizeof...(Args)>::Type array,
- const Args & ... args) {
- if (check(sizeof...(Args) >= ArgList::MAX_PACKED_ARGS))
- set_types(array, args...);
- store_args<Formatter>(array, args...);
- return ArgList(make_type(args...), array);
-}
#else
struct ArgType {
@@ -1985,7 +2025,7 @@ class FormatBuf : public std::basic_streambuf<Char> {
int_type overflow(int_type ch = traits_type::eof()) {
if (!traits_type::eq_int_type(ch, traits_type::eof())) {
- size_t size = this->pptr() - start_;
+ size_t size = this->size();
buffer_.resize(size);
buffer_.reserve(size * 2);
@@ -1997,7 +2037,7 @@ class FormatBuf : public std::basic_streambuf<Char> {
}
size_t size() const {
- return this->pptr() - start_;
+ return to_unsigned(this->pptr() - start_);
}
};
} // namespace internal
@@ -2015,18 +2055,20 @@ class FormatBuf : public std::basic_streambuf<Char> {
# define FMT_VARIADIC_VOID(func, arg_type) \
template <typename... Args> \
void func(arg_type arg0, const Args & ... args) { \
- typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \
- func(arg0, fmt::internal::make_arg_list< \
- fmt::BasicFormatter<Char> >(array, args...)); \
+ typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
+ typename ArgArray::Type array{ \
+ ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
+ func(arg0, fmt::ArgList(fmt::internal::make_type(args...), array)); \
}
// Defines a variadic constructor.
# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
template <typename... Args> \
ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
- typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \
- func(arg0, arg1, fmt::internal::make_arg_list< \
- fmt::BasicFormatter<Char> >(array, args...)); \
+ typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
+ typename ArgArray::Type array{ \
+ ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
+ func(arg0, arg1, fmt::ArgList(fmt::internal::make_type(args...), array)); \
}
#else
@@ -2207,7 +2249,8 @@ class BasicWriter {
// Writes a decimal integer.
template <typename Int>
void write_decimal(Int value) {
- typename internal::IntTraits<Int>::MainType abs_value = value;
+ typedef typename internal::IntTraits<Int>::MainType MainType;
+ MainType abs_value = static_cast<MainType>(value);
if (internal::is_negative(value)) {
abs_value = 0 - abs_value;
*write_unsigned_decimal(abs_value, 1) = '-';
@@ -2474,9 +2517,9 @@ void BasicWriter<Char>::write_str(
return;
}
}
- std::size_t precision = spec.precision_;
+ std::size_t precision = static_cast<std::size_t>(spec.precision_);
if (spec.precision_ >= 0 && precision < str_size)
- str_size = spec.precision_;
+ str_size = precision;
write_str(str_value, str_size, spec);
}
@@ -2510,7 +2553,8 @@ typename BasicWriter<Char>::CharPtr
// is specified.
if (prefix_size > 0 && prefix[prefix_size - 1] == '0')
--prefix_size;
- unsigned number_size = prefix_size + spec.precision();
+ unsigned number_size =
+ prefix_size + internal::to_unsigned(spec.precision());
AlignSpec subspec(number_size, '0', ALIGN_NUMERIC);
if (number_size >= width)
return prepare_int_buffer(num_digits, subspec, prefix, prefix_size);
@@ -2564,7 +2608,7 @@ template <typename T, typename Spec>
void BasicWriter<Char>::write_int(T value, Spec spec) {
unsigned prefix_size = 0;
typedef typename internal::IntTraits<T>::MainType UnsignedType;
- UnsignedType abs_value = value;
+ UnsignedType abs_value = static_cast<UnsignedType>(value);
char prefix[4] = "";
if (internal::is_negative(value)) {
prefix[0] = '-';
@@ -2643,8 +2687,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
template <typename Char>
template <typename T>
-void BasicWriter<Char>::write_double(
- T value, const FormatSpec &spec) {
+void BasicWriter<Char>::write_double(T value, const FormatSpec &spec) {
// Check type.
char type = spec.type();
bool upper = false;
@@ -2744,6 +2787,8 @@ void BasicWriter<Char>::write_double(
// Format using snprintf.
Char fill = internal::CharTraits<Char>::cast(spec.fill());
+ unsigned n = 0;
+ Char *start = 0;
for (;;) {
std::size_t buffer_size = buffer_.capacity() - offset;
#ifdef _MSC_VER
@@ -2755,41 +2800,44 @@ void BasicWriter<Char>::write_double(
buffer_size = buffer_.capacity() - offset;
}
#endif
- Char *start = &buffer_[offset];
- int n = internal::CharTraits<Char>::format_float(
+ start = &buffer_[offset];
+ int result = internal::CharTraits<Char>::format_float(
start, buffer_size, format, width_for_sprintf, spec.precision(), value);
- if (n >= 0 && offset + n < buffer_.capacity()) {
- if (sign) {
- if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) ||
- *start != ' ') {
- *(start - 1) = sign;
- sign = 0;
- } else {
- *(start - 1) = fill;
- }
- ++n;
- }
- if (spec.align() == ALIGN_CENTER &&
- spec.width() > static_cast<unsigned>(n)) {
- width = spec.width();
- CharPtr p = grow_buffer(width);
- std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char));
- fill_padding(p, spec.width(), n, fill);
- return;
- }
- if (spec.fill() != ' ' || sign) {
- while (*start == ' ')
- *start++ = fill;
- if (sign)
- *(start - 1) = sign;
- }
- grow_buffer(n);
- return;
+ if (result >= 0) {
+ n = internal::to_unsigned(result);
+ if (offset + n < buffer_.capacity())
+ break; // The buffer is large enough - continue with formatting.
+ buffer_.reserve(offset + n + 1);
+ } else {
+ // If result is negative we ask to increase the capacity by at least 1,
+ // but as std::vector, the buffer grows exponentially.
+ buffer_.reserve(buffer_.capacity() + 1);
}
- // If n is negative we ask to increase the capacity by at least 1,
- // but as std::vector, the buffer grows exponentially.
- buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1);
}
+ if (sign) {
+ if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) ||
+ *start != ' ') {
+ *(start - 1) = sign;
+ sign = 0;
+ } else {
+ *(start - 1) = fill;
+ }
+ ++n;
+ }
+ if (spec.align() == ALIGN_CENTER && spec.width() > n) {
+ width = spec.width();
+ CharPtr p = grow_buffer(width);
+ std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char));
+ fill_padding(p, spec.width(), n, fill);
+ return;
+ }
+ if (spec.fill() != ' ' || sign) {
+ while (*start == ' ')
+ *start++ = fill;
+ if (sign)
+ *(start - 1) = sign;
+ }
+ grow_buffer(n);
}
/**
@@ -2920,22 +2968,21 @@ void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {
output << value;
BasicStringRef<Char> str(&buffer[0], format_buf.size());
- typedef internal::MakeValue< BasicFormatter<Char> > MakeValue;
- internal::Arg arg = MakeValue(str);
- arg.type = static_cast<internal::Arg::Type>(MakeValue::type(str));
- format_str = f.format(format_str, arg);
+ typedef internal::MakeArg< BasicFormatter<Char> > MakeArg;
+ format_str = f.format(format_str, MakeArg(str));
}
// Reports a system error without throwing an exception.
// Can be used to report errors from destructors.
-void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT;
+FMT_API void report_system_error(int error_code,
+ StringRef message) FMT_NOEXCEPT;
#if FMT_USE_WINDOWS_H
/** A Windows error. */
class WindowsError : public SystemError {
private:
- void init(int error_code, CStringRef format_str, ArgList args);
+ FMT_API void init(int error_code, CStringRef format_str, ArgList args);
public:
/**
@@ -2974,7 +3021,8 @@ class WindowsError : public SystemError {
// Reports a Windows error without throwing an exception.
// Can be used to report errors from destructors.
-void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT;
+FMT_API void report_windows_error(int error_code,
+ StringRef message) FMT_NOEXCEPT;
#endif
@@ -2986,7 +3034,7 @@ enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
Example:
print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23);
*/
-void print_colored(Color c, CStringRef format, ArgList args);
+FMT_API void print_colored(Color c, CStringRef format, ArgList args);
/**
\rst
@@ -3018,7 +3066,7 @@ inline std::wstring format(WCStringRef format_str, ArgList args) {
print(stderr, "Don't {}!", "panic");
\endrst
*/
-void print(std::FILE *f, CStringRef format_str, ArgList args);
+FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args);
/**
\rst
@@ -3029,7 +3077,7 @@ void print(std::FILE *f, CStringRef format_str, ArgList args);
print("Elapsed time: {0:.2f} seconds", 1.23);
\endrst
*/
-void print(CStringRef format_str, ArgList args);
+FMT_API void print(CStringRef format_str, ArgList args);
template <typename Char>
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
@@ -3066,7 +3114,7 @@ inline std::wstring sprintf(WCStringRef format, ArgList args) {
fmt::fprintf(stderr, "Don't %s!", "panic");
\endrst
*/
-int fprintf(std::FILE *f, CStringRef format, ArgList args);
+FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args);
/**
\rst
@@ -3132,10 +3180,10 @@ class FormatInt {
explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {}
explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {}
- /**
- Returns the number of characters written to the output buffer.
- */
- std::size_t size() const { return buffer_ - str_ + BUFFER_SIZE - 1; }
+ /** Returns the number of characters written to the output buffer. */
+ std::size_t size() const {
+ return internal::to_unsigned(buffer_ - str_ + BUFFER_SIZE - 1);
+ }
/**
Returns a pointer to the output buffer content. No terminating null
@@ -3165,7 +3213,8 @@ class FormatInt {
// write a terminating null character.
template <typename T>
inline void format_decimal(char *&buffer, T value) {
- typename internal::IntTraits<T>::MainType abs_value = value;
+ typedef typename internal::IntTraits<T>::MainType MainType;
+ MainType abs_value = static_cast<MainType>(value);
if (internal::is_negative(value)) {
*buffer++ = '-';
abs_value = 0 - abs_value;
@@ -3245,10 +3294,11 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
template <typename... Args> \
ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
const Args & ... args) { \
- typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \
+ typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
+ typename ArgArray::Type array{ \
+ ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
- fmt::internal::make_arg_list< \
- fmt::BasicFormatter<Char> >(array, args...)); \
+ fmt::ArgList(fmt::internal::make_type(args...), array)); \
}
#else
// Defines a wrapper for a function taking __VA_ARGS__ arguments
@@ -3361,8 +3411,20 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
print(cerr, "Don't {}!", "panic");
\endrst
*/
-void print(std::ostream &os, CStringRef format_str, ArgList args);
+FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args);
FMT_VARIADIC(void, print, std::ostream &, CStringRef)
+
+/**
+ \rst
+ Prints formatted data to the stream *os*.
+
+ **Example**::
+
+ fprintf(cerr, "Don't %s!", "panic");
+ \endrst
+ */
+FMT_API int fprintf(std::ostream &os, CStringRef format_str, ArgList args);
+FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef)
#endif
namespace internal {
@@ -3374,7 +3436,7 @@ inline bool is_name_start(Char c) {
// Parses an unsigned integer advancing s to the end of the parsed input.
// This function assumes that the first character of s is a digit.
template <typename Char>
-int parse_nonnegative_int(const Char *&s) {
+unsigned parse_nonnegative_int(const Char *&s) {
assert('0' <= *s && *s <= '9');
unsigned value = 0;
do {
@@ -3453,7 +3515,6 @@ inline internal::Arg BasicFormatter<Char>::parse_arg_name(const Char *&s) {
return arg;
}
-// Should be after FormatSpec
template <typename Char>
const Char *BasicFormatter<Char>::format(
const Char *&format_str, const internal::Arg &arg) {
diff --git a/dep/cppformat/posix.cc b/dep/cppformat/cppformat/posix.cc
index 756281a0ebd..c6c2ae2c413 100644
--- a/dep/cppformat/posix.cc
+++ b/dep/cppformat/cppformat/posix.cc
@@ -173,7 +173,7 @@ std::size_t fmt::File::read(void *buffer, std::size_t count) {
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
if (result < 0)
throw SystemError(errno, "cannot read from file");
- return result;
+ return internal::to_unsigned(result);
}
std::size_t fmt::File::write(const void *buffer, std::size_t count) {
@@ -181,7 +181,7 @@ std::size_t fmt::File::write(const void *buffer, std::size_t count) {
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
if (result < 0)
throw SystemError(errno, "cannot write to file");
- return result;
+ return internal::to_unsigned(result);
}
fmt::File fmt::File::dup(int fd) {
diff --git a/dep/cppformat/posix.h b/dep/cppformat/cppformat/posix.h
index 88bcb4f557b..bfbd3851838 100644
--- a/dep/cppformat/posix.h
+++ b/dep/cppformat/cppformat/posix.h
@@ -34,11 +34,17 @@
#endif
#include <errno.h>
-#include <fcntl.h> // for O_RDONLY
+#include <fcntl.h> // for O_RDONLY
+#include <locale.h> // for locale_t
#include <stdio.h>
+#include <stdlib.h> // for strtod_l
#include <cstddef>
+#ifdef __APPLE__
+# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
+#endif
+
#include "format.h"
#ifndef FMT_POSIX
@@ -299,7 +305,8 @@ class File {
// Closes the file.
void close();
- // Returns the file size.
+ // Returns the file size. The size has signed type for consistency with
+ // stat::st_size.
LongLong size() const;
// Attempts to read count bytes from the file into the specified buffer.
@@ -331,6 +338,58 @@ class File {
// Returns the memory page size.
long getpagesize();
+
+#if defined(LC_NUMERIC_MASK) || defined(_MSC_VER)
+# define FMT_LOCALE
+#endif
+
+#ifdef FMT_LOCALE
+// A "C" numeric locale.
+class Locale {
+ private:
+# ifdef _MSC_VER
+ typedef _locale_t locale_t;
+
+ enum { LC_NUMERIC_MASK = LC_NUMERIC };
+
+ static locale_t newlocale(int category_mask, const char *locale, locale_t) {
+ return _create_locale(category_mask, locale);
+ }
+
+ static void freelocale(locale_t locale) {
+ _free_locale(locale);
+ }
+
+ static double strtod_l(const char *nptr, char **endptr, _locale_t locale) {
+ return _strtod_l(nptr, endptr, locale);
+ }
+# endif
+
+ locale_t locale_;
+
+ FMT_DISALLOW_COPY_AND_ASSIGN(Locale);
+
+ public:
+ typedef locale_t Type;
+
+ Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", NULL)) {
+ if (!locale_)
+ throw fmt::SystemError(errno, "cannot create locale");
+ }
+ ~Locale() { freelocale(locale_); }
+
+ Type get() const { return locale_; }
+
+ // Converts string to floating-point number and advances str past the end
+ // of the parsed input.
+ double strtod(const char *&str) const {
+ char *end = 0;
+ double result = strtod_l(str, &end, locale_);
+ str = end;
+ return result;
+ }
+};
+#endif // FMT_LOCALE
} // namespace fmt
#if !FMT_USE_RVALUE_REFERENCES
diff --git a/src/common/Utilities/StringFormat.h b/src/common/Utilities/StringFormat.h
index d85523bc11f..e21b1024e87 100644
--- a/src/common/Utilities/StringFormat.h
+++ b/src/common/Utilities/StringFormat.h
@@ -19,7 +19,7 @@
#ifndef TRINITYCORE_STRING_FORMAT_H
#define TRINITYCORE_STRING_FORMAT_H
-#include "format.h"
+#include "cppformat/format.h"
namespace Trinity
{
diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt
index 10b8e562143..3cc1d20cf5e 100644
--- a/src/server/bnetserver/CMakeLists.txt
+++ b/src/server/bnetserver/CMakeLists.txt
@@ -94,7 +94,7 @@ target_link_libraries(bnetserver
ipc
common
zmqpp
- format
+ cppformat
${MYSQL_LIBRARY}
${OPENSSL_LIBRARIES}
${ZMQ_LIBRARY}
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index af30600fc09..3d6a1cf3a78 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -151,7 +151,7 @@ target_link_libraries(worldserver
gsoap
Detour
zmqpp
- format
+ cppformat
${JEMALLOC_LIBRARY}
${READLINE_LIBRARY}
${TERMCAP_LIBRARY}
diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt
index 32fccaa2038..25ad7c771e8 100644
--- a/src/tools/map_extractor/CMakeLists.txt
+++ b/src/tools/map_extractor/CMakeLists.txt
@@ -30,7 +30,7 @@ add_executable(mapextractor
target_link_libraries(mapextractor
casc
common
- format
+ cppformat
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
${Boost_LIBRARIES}
diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt
index adc3410aa6e..5640ea8be5d 100644
--- a/src/tools/mmaps_generator/CMakeLists.txt
+++ b/src/tools/mmaps_generator/CMakeLists.txt
@@ -39,7 +39,7 @@ target_link_libraries(mmaps_generator
g3dlib
Recast
Detour
- format
+ cppformat
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}