diff --git a/format.cc b/format.cc index c030d378..c9120f98 100644 --- a/format.cc +++ b/format.cc @@ -609,18 +609,43 @@ unsigned fmt::BasicWriter::PrintfParser::ParseHeader( } } } - // Parse flags and width. ParseFlags(spec, s); + // Parse width. if (*s >= '0' && *s <= '9') { spec.width_ = internal::ParseNonnegativeInt(s, error); } else if (*s == '*') { ++s; const ArgInfo &arg = HandleArgIndex(UINT_MAX, error); - if (arg.type <= LAST_INTEGER_TYPE) - spec.width_ = GetIntValue(arg); + ULongLong width = 0; + switch (arg.type) { + case INT: + width = arg.int_value; + if (arg.int_value < 0) { + spec.align_ = ALIGN_LEFT; + width = -width; + } + break; + case UINT: + width = arg.uint_value; + break; + case LONG_LONG: + width = arg.long_long_value; + if (arg.long_long_value < 0) { + spec.align_ = ALIGN_LEFT; + width = -width; + } + break; + case ULONG_LONG: + width = arg.ulong_long_value; + break; + default: + if (!error) + error = "width is not integer"; + } + if (width <= INT_MAX) + spec.width_ = static_cast(width); else if (!error) - error = "width is not integer"; - // TODO: check for negative width + error = "number is too big in format"; } return arg_index; } diff --git a/test/printf-test.cc b/test/printf-test.cc index f48b0e16..91f05609 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -221,6 +221,7 @@ TEST(PrintfTest, Width) { TEST(PrintfTest, DynamicWidth) { EXPECT_EQ(" 42", str(fmt::sprintf("%*d", 5, 42))); + EXPECT_EQ("42 ", str(fmt::sprintf("%*d", -5, 42))); EXPECT_THROW_MSG(fmt::sprintf("%*d", 5.0, 42), FormatError, "width is not integer"); EXPECT_THROW_MSG(fmt::sprintf("%*d"), FormatError,