From fd5c2e909bd8c3d533b10d648a1e805af98253a8 Mon Sep 17 00:00:00 2001 From: vitaut Date: Thu, 11 Jun 2015 08:58:31 -0700 Subject: [PATCH] Report error when using precision with char --- doc/syntax.rst | 5 +++-- format.cc | 6 +----- test/format-test.cc | 6 ++++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/doc/syntax.rst b/doc/syntax.rst index fb38a5c8..b6db4c0b 100644 --- a/doc/syntax.rst +++ b/doc/syntax.rst @@ -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 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 -used from the field content. The *precision* is not allowed for integer values -or pointers. +used from the field content. The *precision* is not allowed for integer, +character, Boolean, and pointer values. 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'``. | +---------+----------------------------------------------------------+ +Integer presentation types can also be used with character and Boolean values. The available presentation types for floating-point values are: +---------+----------------------------------------------------------+ diff --git a/format.cc b/format.cc index e8714a33..a6a85651 100644 --- a/format.cc +++ b/format.cc @@ -663,10 +663,6 @@ class fmt::internal::ArgFormatter : FMT_THROW(FormatError("invalid format specifier for char")); typedef typename fmt::BasicWriter::CharPtr CharPtr; Char fill = static_cast(spec_.fill()); - if (spec_.precision_ == 0) { - std::fill_n(writer_.grow_buffer(spec_.width_), spec_.width_, fill); - return; - } CharPtr out = CharPtr(); if (spec_.width_ > 1) { out = writer_.grow_buffer(spec_.width_); @@ -1197,7 +1193,7 @@ const Char *fmt::BasicFormatter::format( } else { 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::format("precision not allowed in {} format specifier", arg.type == Arg::POINTER ? "pointer" : "integer"))); diff --git a/test/format-test.cc b/test/format-test.cc index 41d48f48..c7c1f596 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1029,6 +1029,8 @@ TEST(FormatterTest, Precision) { FormatError, "precision not allowed in integer format specifier"); EXPECT_THROW_MSG(format("{0:.2f}", 42ull), 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.2345l)); @@ -1037,7 +1039,6 @@ TEST(FormatterTest, Precision) { EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast(0xcafe)), FormatError, "precision not allowed in pointer format specifier"); - EXPECT_EQ(" ", format("{0:3.0}", 'x')); EXPECT_EQ("st", format("{0:.2}", "str")); EXPECT_EQ("te", format("{0:.2}", TestString("test"))); } @@ -1112,6 +1113,8 @@ TEST(FormatterTest, RuntimePrecision) { FormatError, "precision not allowed in integer format specifier"); EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2), 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("{1:.{0}}", 2, 1.2345l)); @@ -1120,7 +1123,6 @@ TEST(FormatterTest, RuntimePrecision) { EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast(0xcafe), 2), 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("te", format("{0:.{1}}", TestString("test"), 2)); }