Report error when using precision with char

This commit is contained in:
vitaut 2015-06-11 08:58:31 -07:00
parent fccff7be5f
commit fd5c2e909b
3 changed files with 8 additions and 9 deletions

View File

@ -162,8 +162,8 @@ displayed after the decimal point for a floating-point value formatted with
``'f'`` and ``'F'``, or before and after the decimal point for a floating-point ``'f'`` and ``'F'``, or before and after the decimal point for a floating-point
value formatted with ``'g'`` or ``'G'``. For non-number types the field value formatted with ``'g'`` or ``'G'``. For non-number types the field
indicates the maximum field size - in other words, how many characters will be indicates the maximum field size - in other words, how many characters will be
used from the field content. The *precision* is not allowed for integer values used from the field content. The *precision* is not allowed for integer,
or pointers. character, Boolean, and pointer values.
Finally, the *type* determines how the data should be presented. Finally, the *type* determines how the data should be presented.
@ -219,6 +219,7 @@ The available integer presentation types are:
| none | The same as ``'d'``. | | none | The same as ``'d'``. |
+---------+----------------------------------------------------------+ +---------+----------------------------------------------------------+
Integer presentation types can also be used with character and Boolean values.
The available presentation types for floating-point values are: The available presentation types for floating-point values are:
+---------+----------------------------------------------------------+ +---------+----------------------------------------------------------+

View File

@ -663,10 +663,6 @@ class fmt::internal::ArgFormatter :
FMT_THROW(FormatError("invalid format specifier for char")); FMT_THROW(FormatError("invalid format specifier for char"));
typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr; typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr;
Char fill = static_cast<Char>(spec_.fill()); Char fill = static_cast<Char>(spec_.fill());
if (spec_.precision_ == 0) {
std::fill_n(writer_.grow_buffer(spec_.width_), spec_.width_, fill);
return;
}
CharPtr out = CharPtr(); CharPtr out = CharPtr();
if (spec_.width_ > 1) { if (spec_.width_ > 1) {
out = writer_.grow_buffer(spec_.width_); out = writer_.grow_buffer(spec_.width_);
@ -1197,7 +1193,7 @@ const Char *fmt::BasicFormatter<Char>::format(
} 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) {
FMT_THROW(FormatError( FMT_THROW(FormatError(
fmt::format("precision not allowed in {} format specifier", fmt::format("precision not allowed in {} format specifier",
arg.type == Arg::POINTER ? "pointer" : "integer"))); arg.type == Arg::POINTER ? "pointer" : "integer")));

View File

@ -1029,6 +1029,8 @@ TEST(FormatterTest, Precision) {
FormatError, "precision not allowed in integer format specifier"); FormatError, "precision not allowed in integer format specifier");
EXPECT_THROW_MSG(format("{0:.2f}", 42ull), EXPECT_THROW_MSG(format("{0:.2f}", 42ull),
FormatError, "precision not allowed in integer format specifier"); FormatError, "precision not allowed in integer format specifier");
EXPECT_THROW_MSG(format("{0:3.0}", 'x'),
FormatError, "precision not allowed in integer format specifier");
EXPECT_EQ("1.2", format("{0:.2}", 1.2345)); EXPECT_EQ("1.2", format("{0:.2}", 1.2345));
EXPECT_EQ("1.2", format("{0:.2}", 1.2345l)); EXPECT_EQ("1.2", format("{0:.2}", 1.2345l));
@ -1037,7 +1039,6 @@ TEST(FormatterTest, Precision) {
EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)), EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)),
FormatError, "precision not allowed in pointer format specifier"); FormatError, "precision not allowed in pointer format specifier");
EXPECT_EQ(" ", format("{0:3.0}", 'x'));
EXPECT_EQ("st", format("{0:.2}", "str")); EXPECT_EQ("st", format("{0:.2}", "str"));
EXPECT_EQ("te", format("{0:.2}", TestString("test"))); EXPECT_EQ("te", format("{0:.2}", TestString("test")));
} }
@ -1112,6 +1113,8 @@ TEST(FormatterTest, RuntimePrecision) {
FormatError, "precision not allowed in integer format specifier"); FormatError, "precision not allowed in integer format specifier");
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2), EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2),
FormatError, "precision not allowed in integer format specifier"); FormatError, "precision not allowed in integer format specifier");
EXPECT_THROW_MSG(format("{0:3.{1}}", 'x', 0),
FormatError, "precision not allowed in integer format specifier");
EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2)); EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2));
EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l)); EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l));
@ -1120,7 +1123,6 @@ TEST(FormatterTest, RuntimePrecision) {
EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2), EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2),
FormatError, "precision not allowed in pointer format specifier"); FormatError, "precision not allowed in pointer format specifier");
EXPECT_EQ(" ", format("{0:3.{1}}", 'x', 0));
EXPECT_EQ("st", format("{0:.{1}}", "str", 2)); EXPECT_EQ("st", format("{0:.{1}}", "str", 2));
EXPECT_EQ("te", format("{0:.{1}}", TestString("test"), 2)); EXPECT_EQ("te", format("{0:.{1}}", TestString("test"), 2));
} }