diff --git a/format.cc b/format.cc index 0606631d..af42cb13 100644 --- a/format.cc +++ b/format.cc @@ -611,12 +611,16 @@ void fmt::BasicWriter::PrintfParser::Format( unsigned arg_index = 0; bool have_width = false, have_arg_index = false; - if (*s >= '0' && *s <= '9') { + c = *s; + if (c >= '0' && c <= '9') { unsigned value = internal::ParseNonnegativeInt(s, error); if (*s != '$') { - // TODO: handle '0' - have_width = true; - spec.width_ = value; + if (c == '0') + spec.fill_ = '0'; + if (value != 0) { + have_width = true; + spec.width_ = value; + } } else { ++s; if (next_arg_index_ <= 0) { @@ -659,9 +663,11 @@ void fmt::BasicWriter::PrintfParser::Format( spec.align_ = ALIGN_LEFT; break; case '+': + // TODO + spec.flags_ |= SIGN_FLAG | PLUS_FLAG; case ' ': case '#': - //++s; + ++s; break; } @@ -725,17 +731,18 @@ void fmt::BasicWriter::PrintfParser::Format( // Parse width and zero flag. if (*s < '0' || *s > '9') break; - if (*s == '0') { - spec.align_ = ALIGN_NUMERIC; + if (*s == '0') spec.fill_ = '0'; - } // Zero may be parsed again as a part of the width, but it is simpler // and more efficient than checking if the next char is a digit. spec.width_ = internal::ParseNonnegativeInt(s, error); // Fall through. default: - if (spec.fill_ == '0' && arg->type > LAST_NUMERIC_TYPE) - throw FormatError("format specifier '0' requires numeric argument"); + if (spec.fill_ == '0') { + spec.align_ = ALIGN_NUMERIC; + if (arg->type > LAST_NUMERIC_TYPE) + throw FormatError("format specifier '0' requires numeric argument"); + } break; } diff --git a/test/printf-test.cc b/test/printf-test.cc index 18b682d7..b2805016 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -124,15 +124,31 @@ TEST(PrintfTest, Width) { // Width cannot be specified twice. EXPECT_THROW_MSG(fmt::sprintf("%5-5d", 42), FormatError, "unknown format code '-' for integer"); -} -TEST(PrintfTest, InvalidWidth) { EXPECT_THROW_MSG(fmt::sprintf(str(Format("%{}d", BIG_NUM)), 42), FormatError, "number is too big in format"); EXPECT_THROW_MSG(fmt::sprintf(str(Format("%1${}d", BIG_NUM)), 42), FormatError, "number is too big in format"); } +TEST(PrintfTest, ZeroFlag) { + EXPECT_EQ("00042", str(fmt::sprintf("%05d", 42))); + EXPECT_EQ("00042", str(fmt::sprintf("%1$05d", 42))); + EXPECT_EQ("-0042", str(fmt::sprintf("%05d", -42))); + EXPECT_EQ("-0042", str(fmt::sprintf("%1$05d", -42))); + + EXPECT_EQ("00042", str(fmt::sprintf("%05d", 42))); + EXPECT_EQ("00042", str(fmt::sprintf("%1$05d", 42))); + EXPECT_EQ("-0042", str(fmt::sprintf("%05d", -42))); + EXPECT_EQ("-0042", str(fmt::sprintf("%1$05d", -42))); + EXPECT_EQ("-004.2", str(fmt::sprintf("%06g", -4.2))); + EXPECT_EQ("-004.2", str(fmt::sprintf("%1$06g", -4.2))); + + EXPECT_EQ("+00042", str(fmt::sprintf("%00+6d", 42))); + + // TODO: test for error if argument is non-numeric +} + // TODO TEST(PrintfTest, Align) {