mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
This commit is contained in:
35
format.cc
35
format.cc
@ -431,8 +431,18 @@ class fmt::internal::ArgFormatter :
|
|||||||
void visit_any_double(T value) { writer_.FormatDouble(value, spec_); }
|
void visit_any_double(T value) { writer_.FormatDouble(value, spec_); }
|
||||||
|
|
||||||
void visit_char(int value) {
|
void visit_char(int value) {
|
||||||
if (spec_.type_ && spec_.type_ != 'c')
|
if (spec_.type_ && spec_.type_ != 'c') {
|
||||||
fmt::internal::ReportUnknownType(spec_.type_, "char");
|
switch (spec_.type_) {
|
||||||
|
// TODO: don't duplicate integer format specifiers here
|
||||||
|
case 'd': case 'x': case 'X': case 'b': case 'B': case 'o':
|
||||||
|
writer_.FormatInt(value, spec_);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
internal::ReportUnknownType(spec_.type_, "char");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
|
||||||
|
throw FormatError("invalid format specifier for char");
|
||||||
typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr;
|
typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr;
|
||||||
CharPtr out = CharPtr();
|
CharPtr out = CharPtr();
|
||||||
if (spec_.width_ > 1) {
|
if (spec_.width_ > 1) {
|
||||||
@ -893,25 +903,17 @@ void fmt::internal::PrintfFormatter<Char>::Format(
|
|||||||
case Arg::ULONG_LONG:
|
case Arg::ULONG_LONG:
|
||||||
writer.FormatInt(arg.ulong_long_value, spec);
|
writer.FormatInt(arg.ulong_long_value, spec);
|
||||||
break;
|
break;
|
||||||
case Arg::DOUBLE:
|
|
||||||
writer.FormatDouble(arg.double_value, spec);
|
|
||||||
break;
|
|
||||||
case Arg::LONG_DOUBLE:
|
|
||||||
writer.FormatDouble(arg.long_double_value, spec);
|
|
||||||
break;
|
|
||||||
case Arg::CHAR: {
|
case Arg::CHAR: {
|
||||||
if (spec.type_ && spec.type_ != 'c')
|
if (spec.type_ && spec.type_ != 'c')
|
||||||
internal::ReportUnknownType(spec.type_, "char");
|
writer.FormatInt(arg.int_value, spec);
|
||||||
typedef typename BasicWriter<Char>::CharPtr CharPtr;
|
typedef typename BasicWriter<Char>::CharPtr CharPtr;
|
||||||
CharPtr out = CharPtr();
|
CharPtr out = CharPtr();
|
||||||
if (spec.width_ > 1) {
|
if (spec.width_ > 1) {
|
||||||
Char fill = static_cast<Char>(spec.fill());
|
Char fill = ' ';
|
||||||
out = writer.GrowBuffer(spec.width_);
|
out = writer.GrowBuffer(spec.width_);
|
||||||
if (spec.align_ == ALIGN_RIGHT) {
|
if (spec.align_ != ALIGN_LEFT) {
|
||||||
std::fill_n(out, spec.width_ - 1, fill);
|
std::fill_n(out, spec.width_ - 1, fill);
|
||||||
out += spec.width_ - 1;
|
out += spec.width_ - 1;
|
||||||
} else if (spec.align_ == ALIGN_CENTER) {
|
|
||||||
out = writer.FillPadding(out, spec.width_, 1, fill);
|
|
||||||
} else {
|
} else {
|
||||||
std::fill_n(out + 1, spec.width_ - 1, fill);
|
std::fill_n(out + 1, spec.width_ - 1, fill);
|
||||||
}
|
}
|
||||||
@ -921,6 +923,12 @@ void fmt::internal::PrintfFormatter<Char>::Format(
|
|||||||
*out = static_cast<Char>(arg.int_value);
|
*out = static_cast<Char>(arg.int_value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Arg::DOUBLE:
|
||||||
|
writer.FormatDouble(arg.double_value, spec);
|
||||||
|
break;
|
||||||
|
case Arg::LONG_DOUBLE:
|
||||||
|
writer.FormatDouble(arg.long_double_value, spec);
|
||||||
|
break;
|
||||||
case Arg::STRING:
|
case Arg::STRING:
|
||||||
writer.write_str(arg.string, spec);
|
writer.write_str(arg.string, spec);
|
||||||
break;
|
break;
|
||||||
@ -1001,6 +1009,7 @@ const Char *fmt::BasicFormatter<Char>::format(
|
|||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
CheckSign(s, arg);
|
CheckSign(s, arg);
|
||||||
|
spec.flags_ |= MINUS_FLAG;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
CheckSign(s, arg);
|
CheckSign(s, arg);
|
||||||
|
6
format.h
6
format.h
@ -569,10 +569,10 @@ struct NonZero<0> {
|
|||||||
struct Arg {
|
struct Arg {
|
||||||
enum Type {
|
enum Type {
|
||||||
// Integer types should go first,
|
// Integer types should go first,
|
||||||
INT, UINT, LONG_LONG, ULONG_LONG, LAST_INTEGER_TYPE = ULONG_LONG,
|
INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR,
|
||||||
// followed by floating-point types.
|
// followed by floating-point types.
|
||||||
DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
|
DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
|
||||||
CHAR, STRING, WSTRING, POINTER, CUSTOM
|
STRING, WSTRING, POINTER, CUSTOM
|
||||||
};
|
};
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
@ -900,7 +900,7 @@ enum Alignment {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Flags.
|
// Flags.
|
||||||
enum { SIGN_FLAG = 1, PLUS_FLAG = 2, HASH_FLAG = 4 };
|
enum { SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8 };
|
||||||
|
|
||||||
// An empty format specifier.
|
// An empty format specifier.
|
||||||
struct EmptySpec {};
|
struct EmptySpec {};
|
||||||
|
@ -696,7 +696,7 @@ TEST(FormatterTest, NumericAlign) {
|
|||||||
EXPECT_THROW_MSG(format("{0:=5", 'c'),
|
EXPECT_THROW_MSG(format("{0:=5", 'c'),
|
||||||
FormatError, "unmatched '{' in format");
|
FormatError, "unmatched '{' in format");
|
||||||
EXPECT_THROW_MSG(format("{0:=5}", 'c'),
|
EXPECT_THROW_MSG(format("{0:=5}", 'c'),
|
||||||
FormatError, "format specifier '=' requires numeric argument");
|
FormatError, "invalid format specifier for char");
|
||||||
EXPECT_THROW_MSG(format("{0:=5}", "abc"),
|
EXPECT_THROW_MSG(format("{0:=5}", "abc"),
|
||||||
FormatError, "format specifier '=' requires numeric argument");
|
FormatError, "format specifier '=' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(format("{0:=8}", reinterpret_cast<void*>(0xface)),
|
EXPECT_THROW_MSG(format("{0:=8}", reinterpret_cast<void*>(0xface)),
|
||||||
@ -760,7 +760,7 @@ TEST(FormatterTest, PlusSign) {
|
|||||||
EXPECT_THROW_MSG(format("{0:+", 'c'),
|
EXPECT_THROW_MSG(format("{0:+", 'c'),
|
||||||
FormatError, "unmatched '{' in format");
|
FormatError, "unmatched '{' in format");
|
||||||
EXPECT_THROW_MSG(format("{0:+}", 'c'),
|
EXPECT_THROW_MSG(format("{0:+}", 'c'),
|
||||||
FormatError, "format specifier '+' requires numeric argument");
|
FormatError, "invalid format specifier for char");
|
||||||
EXPECT_THROW_MSG(format("{0:+}", "abc"),
|
EXPECT_THROW_MSG(format("{0:+}", "abc"),
|
||||||
FormatError, "format specifier '+' requires numeric argument");
|
FormatError, "format specifier '+' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(format("{0:+}", reinterpret_cast<void*>(0x42)),
|
EXPECT_THROW_MSG(format("{0:+}", reinterpret_cast<void*>(0x42)),
|
||||||
@ -786,7 +786,7 @@ TEST(FormatterTest, MinusSign) {
|
|||||||
EXPECT_THROW_MSG(format("{0:-", 'c'),
|
EXPECT_THROW_MSG(format("{0:-", 'c'),
|
||||||
FormatError, "unmatched '{' in format");
|
FormatError, "unmatched '{' in format");
|
||||||
EXPECT_THROW_MSG(format("{0:-}", 'c'),
|
EXPECT_THROW_MSG(format("{0:-}", 'c'),
|
||||||
FormatError, "format specifier '-' requires numeric argument");
|
FormatError, "invalid format specifier for char");
|
||||||
EXPECT_THROW_MSG(format("{0:-}", "abc"),
|
EXPECT_THROW_MSG(format("{0:-}", "abc"),
|
||||||
FormatError, "format specifier '-' requires numeric argument");
|
FormatError, "format specifier '-' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(format("{0:-}", reinterpret_cast<void*>(0x42)),
|
EXPECT_THROW_MSG(format("{0:-}", reinterpret_cast<void*>(0x42)),
|
||||||
@ -812,7 +812,7 @@ TEST(FormatterTest, SpaceSign) {
|
|||||||
EXPECT_THROW_MSG(format("{0: ", 'c'),
|
EXPECT_THROW_MSG(format("{0: ", 'c'),
|
||||||
FormatError, "unmatched '{' in format");
|
FormatError, "unmatched '{' in format");
|
||||||
EXPECT_THROW_MSG(format("{0: }", 'c'),
|
EXPECT_THROW_MSG(format("{0: }", 'c'),
|
||||||
FormatError, "format specifier ' ' requires numeric argument");
|
FormatError, "invalid format specifier for char");
|
||||||
EXPECT_THROW_MSG(format("{0: }", "abc"),
|
EXPECT_THROW_MSG(format("{0: }", "abc"),
|
||||||
FormatError, "format specifier ' ' requires numeric argument");
|
FormatError, "format specifier ' ' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(format("{0: }", reinterpret_cast<void*>(0x42)),
|
EXPECT_THROW_MSG(format("{0: }", reinterpret_cast<void*>(0x42)),
|
||||||
@ -859,7 +859,7 @@ TEST(FormatterTest, HashFlag) {
|
|||||||
EXPECT_THROW_MSG(format("{0:#", 'c'),
|
EXPECT_THROW_MSG(format("{0:#", 'c'),
|
||||||
FormatError, "unmatched '{' in format");
|
FormatError, "unmatched '{' in format");
|
||||||
EXPECT_THROW_MSG(format("{0:#}", 'c'),
|
EXPECT_THROW_MSG(format("{0:#}", 'c'),
|
||||||
FormatError, "format specifier '#' requires numeric argument");
|
FormatError, "invalid format specifier for char");
|
||||||
EXPECT_THROW_MSG(format("{0:#}", "abc"),
|
EXPECT_THROW_MSG(format("{0:#}", "abc"),
|
||||||
FormatError, "format specifier '#' requires numeric argument");
|
FormatError, "format specifier '#' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(format("{0:#}", reinterpret_cast<void*>(0x42)),
|
EXPECT_THROW_MSG(format("{0:#}", reinterpret_cast<void*>(0x42)),
|
||||||
@ -881,7 +881,7 @@ TEST(FormatterTest, ZeroFlag) {
|
|||||||
EXPECT_THROW_MSG(format("{0:0", 'c'),
|
EXPECT_THROW_MSG(format("{0:0", 'c'),
|
||||||
FormatError, "unmatched '{' in format");
|
FormatError, "unmatched '{' in format");
|
||||||
EXPECT_THROW_MSG(format("{0:05}", 'c'),
|
EXPECT_THROW_MSG(format("{0:05}", 'c'),
|
||||||
FormatError, "format specifier '0' requires numeric argument");
|
FormatError, "invalid format specifier for char");
|
||||||
EXPECT_THROW_MSG(format("{0:05}", "abc"),
|
EXPECT_THROW_MSG(format("{0:05}", "abc"),
|
||||||
FormatError, "format specifier '0' requires numeric argument");
|
FormatError, "format specifier '0' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(format("{0:05}", reinterpret_cast<void*>(0x42)),
|
EXPECT_THROW_MSG(format("{0:05}", reinterpret_cast<void*>(0x42)),
|
||||||
@ -1268,7 +1268,7 @@ TEST(FormatterTest, FormatLongDouble) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, FormatChar) {
|
TEST(FormatterTest, FormatChar) {
|
||||||
CheckUnknownTypes('a', "c", "char");
|
CheckUnknownTypes('a', "cbBdoxX", "char");
|
||||||
EXPECT_EQ("a", format("{0}", 'a'));
|
EXPECT_EQ("a", format("{0}", 'a'));
|
||||||
EXPECT_EQ("z", format("{0:c}", 'z'));
|
EXPECT_EQ("z", format("{0:c}", 'z'));
|
||||||
EXPECT_EQ(L"a", format(L"{0}", 'a'));
|
EXPECT_EQ(L"a", format(L"{0}", 'a'));
|
||||||
|
Reference in New Issue
Block a user