Improve error reporting in parse_arg_index.

This commit is contained in:
Victor Zverovich 2014-08-27 09:04:51 -07:00
parent 42de4f1f7d
commit da0f7c0a51
2 changed files with 23 additions and 28 deletions

View File

@ -753,27 +753,24 @@ void fmt::BasicWriter<Char>::write_str(
template <typename Char> template <typename Char>
inline const Arg inline const Arg
&fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) { &fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) {
unsigned arg_index = 0; const Arg *arg = 0;
if (*s < '0' || *s > '9') { if (*s < '0' || *s > '9') {
if (*s != '}' && *s != ':') arg = &next_arg();
throw FormatError("invalid format string"); } else {
const Arg &arg = next_arg(); if (next_arg_index_ > 0)
if (error_) error_ = "cannot switch from automatic to manual argument indexing";
throw FormatError(error_); next_arg_index_ = -1;
return arg; 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( throw FormatError(
"cannot switch from automatic to manual argument indexing"); *s != '}' && *s != ':' ? "invalid format string" : error_);
} }
next_arg_index_ = -1; return *arg;
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];
} }
template <typename Char> template <typename Char>
@ -1198,8 +1195,6 @@ const Char *fmt::BasicFormatter<Char>::format(
if (*s++ != '}') if (*s++ != '}')
throw FormatError("unmatched '{' in format"); throw FormatError("unmatched '{' in format");
if (error_)
throw FormatError(error_);
start_ = s; start_ = s;
// Format argument. // Format argument.

View File

@ -587,7 +587,7 @@ TEST(FormatterTest, Escape) {
TEST(FormatterTest, UnmatchedBraces) { TEST(FormatterTest, UnmatchedBraces) {
EXPECT_THROW_MSG(format("{"), FormatError, "invalid format string"); EXPECT_THROW_MSG(format("{"), FormatError, "invalid format string");
EXPECT_THROW_MSG(format("}"), FormatError, "unmatched '}' in format"); 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) { TEST(FormatterTest, NoArgs) {
@ -607,19 +607,19 @@ TEST(FormatterTest, ArgsInDifferentPositions) {
TEST(FormatterTest, ArgErrors) { TEST(FormatterTest, ArgErrors) {
EXPECT_THROW_MSG(format("{"), FormatError, "invalid format string"); EXPECT_THROW_MSG(format("{"), FormatError, "invalid format string");
EXPECT_THROW_MSG(format("{x}"), 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, EXPECT_THROW_MSG(format("{0}"), FormatError,
"argument index is out of range in format"); "argument index is out of range in format");
char format_str[BUFFER_SIZE]; char format_str[BUFFER_SIZE];
safe_sprintf(format_str, "{%u", INT_MAX); 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); safe_sprintf(format_str, "{%u}", INT_MAX);
EXPECT_THROW_MSG(format(format_str), FormatError, EXPECT_THROW_MSG(format(format_str), FormatError,
"argument index is out of range in format"); "argument index is out of range in format");
safe_sprintf(format_str, "{%u", INT_MAX + 1u); 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); safe_sprintf(format_str, "{%u}", INT_MAX + 1u);
EXPECT_THROW_MSG(format(format_str), FormatError, EXPECT_THROW_MSG(format(format_str), FormatError,
"number is too big in format"); "number is too big in format");
@ -896,7 +896,7 @@ TEST(FormatterTest, Width) {
char format_str[BUFFER_SIZE]; char format_str[BUFFER_SIZE];
safe_sprintf(format_str, "{0:%u", UINT_MAX); safe_sprintf(format_str, "{0:%u", UINT_MAX);
increment(format_str + 3); 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"); "number is too big in format");
std::size_t size = std::strlen(format_str); std::size_t size = std::strlen(format_str);
format_str[size] = '}'; format_str[size] = '}';
@ -905,7 +905,7 @@ TEST(FormatterTest, Width) {
"number is too big in format"); "number is too big in format");
safe_sprintf(format_str, "{0:%u", INT_MAX + 1u); 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"); "number is too big in format");
safe_sprintf(format_str, "{0:%u}", INT_MAX + 1u); safe_sprintf(format_str, "{0:%u}", INT_MAX + 1u);
EXPECT_THROW_MSG(format(format_str, 0), FormatError, EXPECT_THROW_MSG(format(format_str, 0), FormatError,
@ -928,7 +928,7 @@ TEST(FormatterTest, Precision) {
char format_str[BUFFER_SIZE]; char format_str[BUFFER_SIZE];
safe_sprintf(format_str, "{0:.%u", UINT_MAX); safe_sprintf(format_str, "{0:.%u", UINT_MAX);
increment(format_str + 4); 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"); "number is too big in format");
std::size_t size = std::strlen(format_str); std::size_t size = std::strlen(format_str);
format_str[size] = '}'; format_str[size] = '}';
@ -937,7 +937,7 @@ TEST(FormatterTest, Precision) {
"number is too big in format"); "number is too big in format");
safe_sprintf(format_str, "{0:.%u", INT_MAX + 1u); 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"); "number is too big in format");
safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u); safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u);
EXPECT_THROW_MSG(format(format_str, 0), FormatError, EXPECT_THROW_MSG(format(format_str, 0), FormatError,
@ -1002,7 +1002,7 @@ TEST(FormatterTest, RuntimePrecision) {
char format_str[BUFFER_SIZE]; char format_str[BUFFER_SIZE];
safe_sprintf(format_str, "{0:.{%u", UINT_MAX); safe_sprintf(format_str, "{0:.{%u", UINT_MAX);
increment(format_str + 5); 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); std::size_t size = std::strlen(format_str);
format_str[size] = '}'; format_str[size] = '}';
format_str[size + 1] = 0; format_str[size + 1] = 0;