Get rid of FormatterBase::error_.

This commit is contained in:
Victor Zverovich
2014-08-28 07:48:55 -07:00
parent 279c7a6e6a
commit 56fc525e98
2 changed files with 28 additions and 35 deletions

View File

@ -799,20 +799,23 @@ const Arg &fmt::internal::FormatterBase::next_arg(const char *&error) {
} }
const Arg &fmt::internal::FormatterBase::handle_arg_index(unsigned arg_index) { const Arg &fmt::internal::FormatterBase::handle_arg_index(unsigned arg_index) {
if (arg_index != UINT_MAX) { const char *error = 0;
if (next_arg_index_ <= 0) { const Arg *arg = 0;
next_arg_index_ = -1; if (arg_index == UINT_MAX) {
--arg_index; arg = &next_arg(error);
} else if (!error_) { } else {
error_ = "cannot switch from automatic to manual argument indexing"; if (next_arg_index_ > 0)
} error = "cannot switch from automatic to manual argument indexing";
next_arg_index_ = -1;
--arg_index;
if (arg_index < args_.size()) if (arg_index < args_.size())
return args_[arg_index]; arg = &args_[arg_index];
if (!error_) else if (!error)
error_ = "argument index is out of range in format"; error = "argument index is out of range in format";
return DUMMY_ARG;
} }
return next_arg(error_); if (error)
throw FormatError(error);
return *arg;
} }
template <typename Char> template <typename Char>
@ -871,7 +874,7 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
spec.width_ = parse_nonnegative_int(s); spec.width_ = parse_nonnegative_int(s);
} else if (*s == '*') { } else if (*s == '*') {
++s; ++s;
spec.width_ = WidthHandler(spec).visit(handle_arg_index(UINT_MAX)); spec.width_ = WidthHandler(spec).visit(get_arg(s));
} }
return arg_index; return arg_index;
} }
@ -897,17 +900,6 @@ void fmt::internal::PrintfFormatter<Char>::format(
FormatSpec spec; FormatSpec spec;
spec.align_ = ALIGN_RIGHT; spec.align_ = ALIGN_RIGHT;
// Reporting errors is delayed till the format specification is
// completely parsed. This is done to avoid potentially confusing
// error messages for incomplete format strings. For example, in
// sprintf("%2$", 42);
// the format specification is incomplete. In a naive approach we
// would parse 2 as an argument index and report an error that the
// index is out of range which would be rather confusing if the
// use meant "%2d$" rather than "%2$d". If we delay an error, the
// user will get an error that the format string is invalid which
// is OK for both cases.
// Parse argument index, flags and width. // Parse argument index, flags and width.
unsigned arg_index = parse_header(s, spec); unsigned arg_index = parse_header(s, spec);
@ -918,11 +910,11 @@ void fmt::internal::PrintfFormatter<Char>::format(
spec.precision_ = parse_nonnegative_int(s); spec.precision_ = parse_nonnegative_int(s);
} else if (*s == '*') { } else if (*s == '*') {
++s; ++s;
spec.precision_ = PrecisionHandler().visit(handle_arg_index(UINT_MAX)); spec.precision_ = PrecisionHandler().visit(get_arg(s));
} }
} }
Arg arg = handle_arg_index(arg_index); Arg arg = get_arg(s, arg_index);
if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg)) if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg))
spec.flags_ &= ~HASH_FLAG; spec.flags_ &= ~HASH_FLAG;
if (spec.fill_ == '0') { if (spec.fill_ == '0') {
@ -967,8 +959,6 @@ void fmt::internal::PrintfFormatter<Char>::format(
// Parse type. // Parse type.
if (!*s) if (!*s)
throw FormatError("invalid format string"); throw FormatError("invalid format string");
if (error_)
throw FormatError(error_);
spec.type_ = static_cast<char>(*s++); spec.type_ = static_cast<char>(*s++);
if (arg.type <= Arg::LAST_INTEGER_TYPE) { if (arg.type <= Arg::LAST_INTEGER_TYPE) {
// Normalize type. // Normalize type.
@ -1149,8 +1139,6 @@ const Char *fmt::BasicFormatter<Char>::format(
const Arg &precision_arg = parse_arg_index(s); const Arg &precision_arg = parse_arg_index(s);
if (*s++ != '}') if (*s++ != '}')
throw FormatError("unmatched '{' in format"); throw FormatError("unmatched '{' in format");
if (error_)
throw FormatError(error_);
ULongLong value = 0; ULongLong value = 0;
switch (precision_arg.type) { switch (precision_arg.type) {
case Arg::INT: case Arg::INT:

View File

@ -845,12 +845,11 @@ class FormatterBase {
protected: protected:
ArgList args_; ArgList args_;
int next_arg_index_; int next_arg_index_;
const char *error_; // TODO: remove
FormatterBase() : error_(0) {}
const Arg &next_arg(const char *&error); const Arg &next_arg(const char *&error);
// Returns the argument with specified index or, if arg_index is equal
// to the maximum unsigned value, the next argument.
const Arg &handle_arg_index(unsigned arg_index); const Arg &handle_arg_index(unsigned arg_index);
template <typename Char> template <typename Char>
@ -866,10 +865,16 @@ class PrintfFormatter : private FormatterBase {
private: private:
void parse_flags(FormatSpec &spec, const Char *&s); void parse_flags(FormatSpec &spec, const Char *&s);
// Parses argument index, flags and width and returns the parsed // Parses argument index, flags and width and returns the argument index.
// argument index.
unsigned parse_header(const Char *&s, FormatSpec &spec); unsigned parse_header(const Char *&s, FormatSpec &spec);
const Arg &get_arg(const Char *s,
unsigned arg_index = std::numeric_limits<unsigned>::max()) {
if (!*s)
throw FormatError("invalid format string");
return handle_arg_index(arg_index);
}
public: public:
void format(BasicWriter<Char> &writer, void format(BasicWriter<Char> &writer,
BasicStringRef<Char> format, const ArgList &args); BasicStringRef<Char> format, const ArgList &args);