diff --git a/format.cc b/format.cc index 92e323aa..ceadbce8 100644 --- a/format.cc +++ b/format.cc @@ -753,27 +753,24 @@ void fmt::BasicWriter::write_str( template inline const Arg &fmt::BasicFormatter::parse_arg_index(const Char *&s) { - unsigned arg_index = 0; + const Arg *arg = 0; if (*s < '0' || *s > '9') { - if (*s != '}' && *s != ':') - throw FormatError("invalid format string"); - const Arg &arg = next_arg(); - if (error_) - throw FormatError(error_); - return arg; + arg = &next_arg(); + } else { + if (next_arg_index_ > 0) + error_ = "cannot switch from automatic to manual argument indexing"; + next_arg_index_ = -1; + unsigned arg_index = parse_nonnegative_int(s, error_); + if (arg_index < args_.size()) + arg = &args_[arg_index]; + else if (!error_) + error_ = "argument index is out of range in format"; } - if (next_arg_index_ > 0) { + if (error_) { throw FormatError( - "cannot switch from automatic to manual argument indexing"); + *s != '}' && *s != ':' ? "invalid format string" : error_); } - next_arg_index_ = -1; - arg_index = parse_nonnegative_int(s, error_); - if (arg_index >= args_.size()) { - if (!error_) - error_ = "argument index is out of range in format"; - return DUMMY_ARG; - } - return args_[arg_index]; + return *arg; } template @@ -1198,8 +1195,6 @@ const Char *fmt::BasicFormatter::format( if (*s++ != '}') throw FormatError("unmatched '{' in format"); - if (error_) - throw FormatError(error_); start_ = s; // Format argument. diff --git a/test/format-test.cc b/test/format-test.cc index bbe51da0..0fbff0bb 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -587,7 +587,7 @@ TEST(FormatterTest, Escape) { TEST(FormatterTest, UnmatchedBraces) { EXPECT_THROW_MSG(format("{"), FormatError, "invalid format string"); EXPECT_THROW_MSG(format("}"), FormatError, "unmatched '}' in format"); - EXPECT_THROW_MSG(format("{0{}"), FormatError, "unmatched '{' in format"); + EXPECT_THROW_MSG(format("{0{}"), FormatError, "invalid format string"); } TEST(FormatterTest, NoArgs) { @@ -607,19 +607,19 @@ TEST(FormatterTest, ArgsInDifferentPositions) { TEST(FormatterTest, ArgErrors) { EXPECT_THROW_MSG(format("{"), FormatError, "invalid format string"); EXPECT_THROW_MSG(format("{x}"), FormatError, "invalid format string"); - EXPECT_THROW_MSG(format("{0"), FormatError, "unmatched '{' in format"); + EXPECT_THROW_MSG(format("{0"), FormatError, "invalid format string"); EXPECT_THROW_MSG(format("{0}"), FormatError, "argument index is out of range in format"); char format_str[BUFFER_SIZE]; safe_sprintf(format_str, "{%u", INT_MAX); - EXPECT_THROW_MSG(format(format_str), FormatError, "unmatched '{' in format"); + EXPECT_THROW_MSG(format(format_str), FormatError, "invalid format string"); safe_sprintf(format_str, "{%u}", INT_MAX); EXPECT_THROW_MSG(format(format_str), FormatError, "argument index is out of range in format"); safe_sprintf(format_str, "{%u", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str), FormatError, "unmatched '{' in format"); + EXPECT_THROW_MSG(format(format_str), FormatError, "invalid format string"); safe_sprintf(format_str, "{%u}", INT_MAX + 1u); EXPECT_THROW_MSG(format(format_str), FormatError, "number is too big in format"); @@ -896,7 +896,7 @@ TEST(FormatterTest, Width) { char format_str[BUFFER_SIZE]; safe_sprintf(format_str, "{0:%u", UINT_MAX); increment(format_str + 3); - EXPECT_THROW_MSG(format(format_str), FormatError, + EXPECT_THROW_MSG(format(format_str, 0), FormatError, "number is too big in format"); std::size_t size = std::strlen(format_str); format_str[size] = '}'; @@ -905,7 +905,7 @@ TEST(FormatterTest, Width) { "number is too big in format"); safe_sprintf(format_str, "{0:%u", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str), FormatError, + EXPECT_THROW_MSG(format(format_str, 0), FormatError, "number is too big in format"); safe_sprintf(format_str, "{0:%u}", INT_MAX + 1u); EXPECT_THROW_MSG(format(format_str, 0), FormatError, @@ -928,7 +928,7 @@ TEST(FormatterTest, Precision) { char format_str[BUFFER_SIZE]; safe_sprintf(format_str, "{0:.%u", UINT_MAX); increment(format_str + 4); - EXPECT_THROW_MSG(format(format_str), FormatError, + EXPECT_THROW_MSG(format(format_str, 0), FormatError, "number is too big in format"); std::size_t size = std::strlen(format_str); format_str[size] = '}'; @@ -937,7 +937,7 @@ TEST(FormatterTest, Precision) { "number is too big in format"); safe_sprintf(format_str, "{0:.%u", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str), FormatError, + EXPECT_THROW_MSG(format(format_str, 0), FormatError, "number is too big in format"); safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u); EXPECT_THROW_MSG(format(format_str, 0), FormatError, @@ -1002,7 +1002,7 @@ TEST(FormatterTest, RuntimePrecision) { char format_str[BUFFER_SIZE]; safe_sprintf(format_str, "{0:.{%u", UINT_MAX); increment(format_str + 5); - EXPECT_THROW_MSG(format(format_str), FormatError, "unmatched '{' in format"); + EXPECT_THROW_MSG(format(format_str, 0), FormatError, "invalid format string"); std::size_t size = std::strlen(format_str); format_str[size] = '}'; format_str[size + 1] = 0;