forked from fmtlib/fmt
Get rid of FormatterBase::error_.
This commit is contained in:
48
format.cc
48
format.cc
@ -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:
|
||||||
|
15
format.h
15
format.h
@ -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);
|
||||||
|
Reference in New Issue
Block a user