updated to latest cppformat

This commit is contained in:
gabime 2015-11-26 14:50:44 +02:00
parent cbc8ba7203
commit 7b3fc4ba97
2 changed files with 2987 additions and 2620 deletions

View File

@ -1,29 +1,29 @@
/* /*
Formatting library for C++ Formatting library for C++
Copyright (c) 2012 - 2015, Victor Zverovich Copyright (c) 2012 - 2015, Victor Zverovich
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this 1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, 2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "format.h" #include "format.h"
@ -34,6 +34,7 @@
#include <climits> #include <climits>
#include <cmath> #include <cmath>
#include <cstdarg> #include <cstdarg>
#include <cstddef> // for std::ptrdiff_t
#if defined(_WIN32) && defined(__MINGW32__) #if defined(_WIN32) && defined(__MINGW32__)
# include <cstring> # include <cstring>
@ -133,7 +134,9 @@ struct IntChecker {
unsigned max = INT_MAX; unsigned max = INT_MAX;
return value <= max; return value <= max;
} }
static bool fits_in_int(bool) { return true; } static bool fits_in_int(bool) {
return true;
}
}; };
template <> template <>
@ -142,12 +145,14 @@ struct IntChecker<true> {
static bool fits_in_int(T value) { static bool fits_in_int(T value) {
return value >= INT_MIN && value <= INT_MAX; return value >= INT_MIN && value <= INT_MAX;
} }
static bool fits_in_int(int) { return true; } static bool fits_in_int(int) {
return true;
}
}; };
const char RESET_COLOR[] = "\x1b[0m"; const char RESET_COLOR[] = "\x1b[0m";
typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef); typedef void(*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
// Portable thread-safe version of strerror. // Portable thread-safe version of strerror.
// Sets buffer to point to a string describing the error code. // Sets buffer to point to a string describing the error code.
@ -159,7 +164,7 @@ typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
// other - failure // other - failure
// Buffer should be at least of size 1. // Buffer should be at least of size 1.
int safe_strerror( int safe_strerror(
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT { int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT{
FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer"); FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
class StrError { class StrError {
@ -218,7 +223,7 @@ int safe_strerror(
} }
void format_error_code(fmt::Writer &out, int error_code, void format_error_code(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT { fmt::StringRef message) FMT_NOEXCEPT{
// Report error code making sure that the output fits into // Report error code making sure that the output fits into
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
// bad_alloc. // bad_alloc.
@ -236,7 +241,7 @@ void format_error_code(fmt::Writer &out, int error_code,
} }
void report_error(FormatFunc func, void report_error(FormatFunc func,
int error_code, fmt::StringRef message) FMT_NOEXCEPT { int error_code, fmt::StringRef message) FMT_NOEXCEPT{
fmt::MemoryWriter full_message; fmt::MemoryWriter full_message;
func(full_message, error_code, message); func(full_message, error_code, message);
// Use Writer::data instead of Writer::c_str to avoid potential memory // Use Writer::data instead of Writer::c_str to avoid potential memory
@ -247,9 +252,11 @@ void report_error(FormatFunc func,
// IsZeroInt::visit(arg) returns true iff arg is a zero integer. // IsZeroInt::visit(arg) returns true iff arg is a zero integer.
class IsZeroInt : public fmt::internal::ArgVisitor<IsZeroInt, bool> { class IsZeroInt : public fmt::internal::ArgVisitor<IsZeroInt, bool> {
public: public:
template <typename T> template <typename T>
bool visit_any_int(T value) { return value == 0; } bool visit_any_int(T value) {
return value == 0;
}
}; };
// Parses an unsigned integer advancing s to the end of the parsed input. // Parses an unsigned integer advancing s to the end of the parsed input.
@ -299,12 +306,12 @@ void check_sign(const Char *&s, const Arg &arg) {
// Checks if an argument is a valid printf width specifier and sets // Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative. // left alignment if it is negative.
class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> { class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> {
private: private:
fmt::FormatSpec &spec_; fmt::FormatSpec &spec_;
FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler); FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
public: public:
explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {} explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {}
void report_unhandled_arg() { void report_unhandled_arg() {
@ -327,7 +334,7 @@ class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> {
class PrecisionHandler : class PrecisionHandler :
public fmt::internal::ArgVisitor<PrecisionHandler, int> { public fmt::internal::ArgVisitor<PrecisionHandler, int> {
public: public:
void report_unhandled_arg() { void report_unhandled_arg() {
FMT_THROW(fmt::FormatError("precision is not integer")); FMT_THROW(fmt::FormatError("precision is not integer"));
} }
@ -343,16 +350,21 @@ class PrecisionHandler :
// Converts an integer argument to an integral type T for printf. // Converts an integer argument to an integral type T for printf.
template <typename T> template <typename T>
class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> { class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> {
private: private:
fmt::internal::Arg &arg_; fmt::internal::Arg &arg_;
wchar_t type_; wchar_t type_;
FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter); FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
public: public:
ArgConverter(fmt::internal::Arg &arg, wchar_t type) ArgConverter(fmt::internal::Arg &arg, wchar_t type)
: arg_(arg), type_(type) {} : arg_(arg), type_(type) {}
void visit_bool(bool value) {
if (type_ != 's')
visit_any_int(value);
}
template <typename U> template <typename U>
void visit_any_int(U value) { void visit_any_int(U value) {
bool is_signed = type_ == 'd' || type_ == 'i'; bool is_signed = type_ == 'd' || type_ == 'i';
@ -362,17 +374,20 @@ class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> {
if (is_signed) { if (is_signed) {
arg_.type = Arg::INT; arg_.type = Arg::INT;
arg_.int_value = static_cast<int>(static_cast<T>(value)); arg_.int_value = static_cast<int>(static_cast<T>(value));
} else { }
else {
arg_.type = Arg::UINT; arg_.type = Arg::UINT;
arg_.uint_value = static_cast<unsigned>( arg_.uint_value = static_cast<unsigned>(
static_cast<typename fmt::internal::MakeUnsigned<T>::Type>(value)); static_cast<typename fmt::internal::MakeUnsigned<T>::Type>(value));
} }
} else { }
else {
if (is_signed) { if (is_signed) {
arg_.type = Arg::LONG_LONG; arg_.type = Arg::LONG_LONG;
arg_.long_long_value = arg_.long_long_value =
static_cast<typename fmt::internal::MakeUnsigned<U>::Type>(value); static_cast<typename fmt::internal::MakeUnsigned<U>::Type>(value);
} else { }
else {
arg_.type = Arg::ULONG_LONG; arg_.type = Arg::ULONG_LONG;
arg_.ulong_long_value = arg_.ulong_long_value =
static_cast<typename fmt::internal::MakeUnsigned<U>::Type>(value); static_cast<typename fmt::internal::MakeUnsigned<U>::Type>(value);
@ -383,12 +398,12 @@ class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> {
// Converts an integer argument to char for printf. // Converts an integer argument to char for printf.
class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> { class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> {
private: private:
fmt::internal::Arg &arg_; fmt::internal::Arg &arg_;
FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter); FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
public: public:
explicit CharConverter(fmt::internal::Arg &arg) : arg_(arg) {} explicit CharConverter(fmt::internal::Arg &arg) : arg_(arg) {}
template <typename T> template <typename T>
@ -403,34 +418,55 @@ namespace internal {
template <typename Impl, typename Char> template <typename Impl, typename Char>
class BasicArgFormatter : public ArgVisitor<Impl, void> { class BasicArgFormatter : public ArgVisitor<Impl, void> {
private: private:
BasicWriter<Char> &writer_; BasicWriter<Char> &writer_;
FormatSpec &spec_; FormatSpec &spec_;
FMT_DISALLOW_COPY_AND_ASSIGN(BasicArgFormatter); FMT_DISALLOW_COPY_AND_ASSIGN(BasicArgFormatter);
protected: void write_pointer(const void *p) {
BasicWriter<Char> &writer() { return writer_; } spec_.flags_ = HASH_FLAG;
const FormatSpec &spec() const { return spec_; } spec_.type_ = 'x';
writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
}
public: protected:
BasicWriter<Char> &writer() {
return writer_;
}
FormatSpec &spec() {
return spec_;
}
void write(bool value) {
const char *str_value = value ? "true" : "false";
Arg::StringValue<char> str = { str_value, strlen(str_value) };
writer_.write_str(str, spec_);
}
void write(const char *value) {
Arg::StringValue<char> str = { value, value != 0 ? strlen(value) : 0 };
writer_.write_str(str, spec_);
}
public:
BasicArgFormatter(BasicWriter<Char> &w, FormatSpec &s) BasicArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
: writer_(w), spec_(s) {} : writer_(w), spec_(s) {}
template <typename T> template <typename T>
void visit_any_int(T value) { writer_.write_int(value, spec_); } void visit_any_int(T value) {
writer_.write_int(value, spec_);
}
template <typename T> template <typename T>
void visit_any_double(T value) { writer_.write_double(value, spec_); } void visit_any_double(T value) {
writer_.write_double(value, spec_);
}
void visit_bool(bool value) { void visit_bool(bool value) {
if (spec_.type_) { if (spec_.type_)
writer_.write_int(value, spec_); return visit_any_int(value);
return; write(value);
}
const char *str_value = value ? "true" : "false";
Arg::StringValue<char> str = { str_value, strlen(str_value) };
writer_.write_str(str, spec_);
} }
void visit_char(int value) { void visit_char(int value) {
@ -450,18 +486,27 @@ class BasicArgFormatter : public ArgVisitor<Impl, void> {
if (spec_.align_ == ALIGN_RIGHT) { if (spec_.align_ == ALIGN_RIGHT) {
std::fill_n(out, spec_.width_ - CHAR_WIDTH, fill); std::fill_n(out, spec_.width_ - CHAR_WIDTH, fill);
out += spec_.width_ - CHAR_WIDTH; out += spec_.width_ - CHAR_WIDTH;
} else if (spec_.align_ == ALIGN_CENTER) { }
else if (spec_.align_ == ALIGN_CENTER) {
out = writer_.fill_padding(out, spec_.width_, out = writer_.fill_padding(out, spec_.width_,
internal::check(CHAR_WIDTH), fill); internal::check(CHAR_WIDTH), fill);
} else { }
else {
std::fill_n(out + CHAR_WIDTH, spec_.width_ - CHAR_WIDTH, fill); std::fill_n(out + CHAR_WIDTH, spec_.width_ - CHAR_WIDTH, fill);
} }
} else { }
else {
out = writer_.grow_buffer(CHAR_WIDTH); out = writer_.grow_buffer(CHAR_WIDTH);
} }
*out = internal::CharTraits<Char>::cast(value); *out = internal::CharTraits<Char>::cast(value);
} }
void visit_cstring(const char *value) {
if (spec_.type_ == 'p')
return write_pointer(value);
write(value);
}
void visit_string(Arg::StringValue<char> value) { void visit_string(Arg::StringValue<char> value) {
writer_.write_str(value, spec_); writer_.write_str(value, spec_);
} }
@ -475,20 +520,18 @@ class BasicArgFormatter : public ArgVisitor<Impl, void> {
void visit_pointer(const void *value) { void visit_pointer(const void *value) {
if (spec_.type_ && spec_.type_ != 'p') if (spec_.type_ && spec_.type_ != 'p')
report_unknown_type(spec_.type_, "pointer"); report_unknown_type(spec_.type_, "pointer");
spec_.flags_ = HASH_FLAG; write_pointer(value);
spec_.type_ = 'x';
writer_.write_int(reinterpret_cast<uintptr_t>(value), spec_);
} }
}; };
// An argument formatter. // An argument formatter.
template <typename Char> template <typename Char>
class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> { class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
private: private:
BasicFormatter<Char> &formatter_; BasicFormatter<Char> &formatter_;
const Char *format_; const Char *format_;
public: public:
ArgFormatter(BasicFormatter<Char> &f, FormatSpec &s, const Char *fmt) ArgFormatter(BasicFormatter<Char> &f, FormatSpec &s, const Char *fmt)
: BasicArgFormatter<ArgFormatter<Char>, Char>(f.writer(), s), : BasicArgFormatter<ArgFormatter<Char>, Char>(f.writer(), s),
formatter_(f), format_(fmt) {} formatter_(f), format_(fmt) {}
@ -501,10 +544,26 @@ class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
template <typename Char> template <typename Char>
class PrintfArgFormatter : class PrintfArgFormatter :
public BasicArgFormatter<PrintfArgFormatter<Char>, Char> { public BasicArgFormatter<PrintfArgFormatter<Char>, Char> {
public:
void write_null_pointer() {
this->spec().type_ = 0;
this->write("(nil)");
}
typedef BasicArgFormatter<PrintfArgFormatter<Char>, Char> Base;
public:
PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s) PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
: BasicArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {} : BasicArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {}
void visit_bool(bool value) {
FormatSpec &fmt_spec = this->spec();
if (fmt_spec.type_ != 's')
return this->visit_any_int(value);
fmt_spec.type_ = 0;
this->write(value);
}
void visit_char(int value) { void visit_char(int value) {
const FormatSpec &fmt_spec = this->spec(); const FormatSpec &fmt_spec = this->spec();
BasicWriter<Char> &w = this->writer(); BasicWriter<Char> &w = this->writer();
@ -518,18 +577,36 @@ class PrintfArgFormatter :
if (fmt_spec.align_ != ALIGN_LEFT) { if (fmt_spec.align_ != ALIGN_LEFT) {
std::fill_n(out, fmt_spec.width_ - 1, fill); std::fill_n(out, fmt_spec.width_ - 1, fill);
out += fmt_spec.width_ - 1; out += fmt_spec.width_ - 1;
} else { }
else {
std::fill_n(out + 1, fmt_spec.width_ - 1, fill); std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
} }
} else { }
else {
out = w.grow_buffer(1); out = w.grow_buffer(1);
} }
*out = static_cast<Char>(value); *out = static_cast<Char>(value);
} }
void visit_cstring(const char *value) {
if (value)
Base::visit_cstring(value);
else if (this->spec().type_ == 'p')
write_null_pointer();
else
this->write("(null)");
}
void visit_pointer(const void *value) {
if (value)
return Base::visit_pointer(value);
this->spec().type_ = 0;
write_null_pointer();
}
void visit_custom(Arg::CustomValue c) { void visit_custom(Arg::CustomValue c) {
BasicFormatter<Char> formatter(ArgList(), this->writer()); BasicFormatter<Char> formatter(ArgList(), this->writer());
const Char format_str[] = {'}', 0}; const Char format_str[] = { '}', 0 };
const Char *format = format_str; const Char *format = format_str;
c.format(&formatter, c.value, &format); c.format(&formatter, c.value, &format);
} }
@ -672,18 +749,22 @@ FMT_FUNC void fmt::WindowsError::init(
FMT_FUNC void fmt::internal::format_windows_error( FMT_FUNC void fmt::internal::format_windows_error(
fmt::Writer &out, int error_code, fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT { fmt::StringRef message) FMT_NOEXCEPT{
class String { class String {
private: private:
LPWSTR str_; LPWSTR str_;
public: public:
String() : str_() {} String() : str_() {}
~String() { LocalFree(str_); } ~String() {
LPWSTR *ptr() { return &str_; } LocalFree(str_);
}
LPWSTR *ptr() {
return &str_;
}
LPCWSTR c_str() const { return str_; } LPCWSTR c_str() const { return str_; }
}; };
FMT_TRY { FMT_TRY{
String system_message; String system_message;
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
@ -696,15 +777,15 @@ FMT_FUNC void fmt::internal::format_windows_error(
} }
} }
} FMT_CATCH(...) {} } FMT_CATCH(...) {}
format_error_code(out, error_code, message); fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
} }
#endif // FMT_USE_WINDOWS_H #endif // FMT_USE_WINDOWS_H
FMT_FUNC void fmt::internal::format_system_error( FMT_FUNC void fmt::internal::format_system_error(
fmt::Writer &out, int error_code, fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT { fmt::StringRef message) FMT_NOEXCEPT{
FMT_TRY { FMT_TRY{
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer; MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
buffer.resize(INLINE_BUFFER_SIZE); buffer.resize(INLINE_BUFFER_SIZE);
for (;;) { for (;;) {
@ -719,7 +800,7 @@ FMT_FUNC void fmt::internal::format_system_error(
buffer.resize(buffer.size() * 2); buffer.resize(buffer.size() * 2);
} }
} FMT_CATCH(...) {} } FMT_CATCH(...) {}
format_error_code(out, error_code, message); fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
} }
template <typename Char> template <typename Char>
@ -741,7 +822,8 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
map_.insert(Pair(named_arg->name, *named_arg)); map_.insert(Pair(named_arg->name, *named_arg));
break; break;
default: default:
/*nothing*/; /*nothing*/
;
} }
} }
return; return;
@ -762,7 +844,8 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
map_.insert(Pair(named_arg->name, *named_arg)); map_.insert(Pair(named_arg->name, *named_arg));
break; break;
default: default:
/*nothing*/; /*nothing*/
;
} }
} }
} }
@ -787,8 +870,6 @@ void fmt::BasicWriter<Char>::write_str(
FMT_THROW(FormatError("string pointer is null")); FMT_THROW(FormatError("string pointer is null"));
return; return;
} }
if (*str_value)
str_size = std::char_traits<StrChar>::length(str_value);
} }
std::size_t precision = spec.precision_; std::size_t precision = spec.precision_;
if (spec.precision_ >= 0 && precision < str_size) if (spec.precision_ >= 0 && precision < str_size)
@ -846,7 +927,8 @@ FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
case Arg::NAMED_ARG: case Arg::NAMED_ARG:
arg = *static_cast<const internal::Arg*>(arg.pointer); arg = *static_cast<const internal::Arg*>(arg.pointer);
default: default:
/*nothing*/; /*nothing*/
;
} }
return arg; return arg;
} }
@ -924,7 +1006,8 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
if (*s == '$') { // value is an argument index if (*s == '$') { // value is an argument index
++s; ++s;
arg_index = value; arg_index = value;
} else { }
else {
if (c == '0') if (c == '0')
spec.fill_ = '0'; spec.fill_ = '0';
if (value != 0) { if (value != 0) {
@ -939,7 +1022,8 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
// Parse width. // Parse width.
if (*s >= '0' && *s <= '9') { if (*s >= '0' && *s <= '9') {
spec.width_ = parse_nonnegative_int(s); spec.width_ = parse_nonnegative_int(s);
} else if (*s == '*') { }
else if (*s == '*') {
++s; ++s;
spec.width_ = WidthHandler(spec).visit(get_arg(s)); spec.width_ = WidthHandler(spec).visit(get_arg(s));
} }
@ -972,7 +1056,8 @@ void fmt::internal::PrintfFormatter<Char>::format(
++s; ++s;
if ('0' <= *s && *s <= '9') { if ('0' <= *s && *s <= '9') {
spec.precision_ = parse_nonnegative_int(s); spec.precision_ = parse_nonnegative_int(s);
} else if (*s == '*') { }
else if (*s == '*') {
++s; ++s;
spec.precision_ = PrecisionHandler().visit(get_arg(s)); spec.precision_ = PrecisionHandler().visit(get_arg(s));
} }
@ -1006,10 +1091,10 @@ void fmt::internal::PrintfFormatter<Char>::format(
ArgConverter<intmax_t>(arg, *s).visit(arg); ArgConverter<intmax_t>(arg, *s).visit(arg);
break; break;
case 'z': case 'z':
ArgConverter<size_t>(arg, *s).visit(arg); ArgConverter<std::size_t>(arg, *s).visit(arg);
break; break;
case 't': case 't':
ArgConverter<ptrdiff_t>(arg, *s).visit(arg); ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
break; break;
case 'L': case 'L':
// printf produces garbage when 'L' is omitted for long double, no // printf produces garbage when 'L' is omitted for long double, no
@ -1027,7 +1112,8 @@ void fmt::internal::PrintfFormatter<Char>::format(
if (arg.type <= Arg::LAST_INTEGER_TYPE) { if (arg.type <= Arg::LAST_INTEGER_TYPE) {
// Normalize type. // Normalize type.
switch (spec.type_) { switch (spec.type_) {
case 'i': case 'u': case 'i':
case 'u':
spec.type_ = 'd'; spec.type_ = 'd';
break; break;
case 'c': case 'c':
@ -1082,7 +1168,8 @@ const Char *fmt::BasicFormatter<Char>::format(
FMT_THROW(FormatError("invalid fill character '{'")); FMT_THROW(FormatError("invalid fill character '{'"));
s += 2; s += 2;
spec.fill_ = c; spec.fill_ = c;
} else ++s; }
else ++s;
if (spec.align_ == ALIGN_NUMERIC) if (spec.align_ == ALIGN_NUMERIC)
require_numeric_argument(arg, '='); require_numeric_argument(arg, '=');
break; break;
@ -1123,7 +1210,8 @@ const Char *fmt::BasicFormatter<Char>::format(
// Parse width. // Parse width.
if ('0' <= *s && *s <= '9') { if ('0' <= *s && *s <= '9') {
spec.width_ = parse_nonnegative_int(s); spec.width_ = parse_nonnegative_int(s);
} else if (*s == '{') { }
else if (*s == '{') {
++s; ++s;
Arg width_arg = is_name_start(*s) ? Arg width_arg = is_name_start(*s) ?
parse_arg_name(s) : parse_arg_index(s); parse_arg_name(s) : parse_arg_index(s);
@ -1161,7 +1249,8 @@ const Char *fmt::BasicFormatter<Char>::format(
spec.precision_ = 0; spec.precision_ = 0;
if ('0' <= *s && *s <= '9') { if ('0' <= *s && *s <= '9') {
spec.precision_ = parse_nonnegative_int(s); spec.precision_ = parse_nonnegative_int(s);
} else if (*s == '{') { }
else if (*s == '{') {
++s; ++s;
Arg precision_arg = Arg precision_arg =
is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s); is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s);
@ -1191,7 +1280,8 @@ const Char *fmt::BasicFormatter<Char>::format(
if (value > INT_MAX) if (value > INT_MAX)
FMT_THROW(FormatError("number is too big")); FMT_THROW(FormatError("number is too big"));
spec.precision_ = static_cast<int>(value); spec.precision_ = static_cast<int>(value);
} else { }
else {
FMT_THROW(FormatError("missing precision specifier")); FMT_THROW(FormatError("missing precision specifier"));
} }
if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) { if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
@ -1236,14 +1326,16 @@ void fmt::BasicFormatter<Char>::format(BasicCStringRef<Char> format_str) {
} }
FMT_FUNC void fmt::report_system_error( FMT_FUNC void fmt::report_system_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT { int error_code, fmt::StringRef message) FMT_NOEXCEPT{
report_error(internal::format_system_error, error_code, message); // 'fmt::' is for bcc32.
fmt::report_error(internal::format_system_error, error_code, message);
} }
#if FMT_USE_WINDOWS_H #if FMT_USE_WINDOWS_H
FMT_FUNC void fmt::report_windows_error( FMT_FUNC void fmt::report_windows_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT { int error_code, fmt::StringRef message) FMT_NOEXCEPT{
report_error(internal::format_windows_error, error_code, message); // 'fmt::' is for bcc32.
fmt::report_error(internal::format_windows_error, error_code, message);
} }
#endif #endif

File diff suppressed because it is too large Load Diff