From c57d7a506fd60d083c4e7d178b62d6bbaf3c8703 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 28 Aug 2014 08:05:47 -0700 Subject: [PATCH] Factor out argument processing logic common between format and printf to FormatterBase::{next_arg,get_arg}. --- format.cc | 63 ++++++++++++++++++++++++------------------------------- format.h | 20 ++++++++---------- 2 files changed, 36 insertions(+), 47 deletions(-) diff --git a/format.cc b/format.cc index 0d01e70e..4690d144 100644 --- a/format.cc +++ b/format.cc @@ -148,8 +148,6 @@ void report_error(FormatFunc func, } catch (...) {} } -const Arg DUMMY_ARG = {Arg::INT, {0}}; - // IsZeroInt::visit(arg) returns true iff arg is a zero integer. class IsZeroInt : public fmt::internal::ArgVisitor { public: @@ -752,20 +750,9 @@ void fmt::BasicWriter::write_str( template inline const Arg &fmt::BasicFormatter::parse_arg_index(const Char *&s) { - const Arg *arg = 0; const char *error = 0; - if (*s < '0' || *s > '9') { - arg = &next_arg(error); - } 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); - if (arg_index < args_.size()) - arg = &args_[arg_index]; - else if (!error) - error = "argument index is out of range in format"; - } + const Arg *arg = *s < '0' || *s > '9' ? + next_arg(error) : get_arg(parse_nonnegative_int(s), error); if (error) throw FormatError(*s != '}' && *s != ':' ? "invalid format string" : error); return *arg; @@ -786,36 +773,29 @@ void fmt::BasicFormatter::check_sign( ++s; } -const Arg &fmt::internal::FormatterBase::next_arg(const char *&error) { +const Arg *fmt::internal::FormatterBase::next_arg(const char *&error) { if (next_arg_index_ < 0) { error = "cannot switch from manual to automatic argument indexing"; - return DUMMY_ARG; + return 0; } unsigned arg_index = next_arg_index_++; if (arg_index < args_.size()) - return args_[arg_index]; + return &args_[arg_index]; error = "argument index is out of range in format"; - return DUMMY_ARG; + return 0; } -const Arg &fmt::internal::FormatterBase::handle_arg_index(unsigned arg_index) { - const char *error = 0; - const Arg *arg = 0; - if (arg_index == UINT_MAX) { - arg = &next_arg(error); - } else { - 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()) - arg = &args_[arg_index]; - else if (!error) - error = "argument index is out of range in format"; +const Arg *fmt::internal::FormatterBase::get_arg( + unsigned arg_index, const char *&error) { + if (next_arg_index_ > 0) { + error = "cannot switch from automatic to manual argument indexing"; + return 0; } - if (error) - throw FormatError(error); - return *arg; + next_arg_index_ = -1; + if (arg_index < args_.size()) + return &args_[arg_index]; + error = "argument index is out of range in format"; + return 0; } template @@ -845,6 +825,17 @@ void fmt::internal::PrintfFormatter::parse_flags( } } +template +const Arg &fmt::internal::PrintfFormatter::get_arg( + const Char *s, unsigned arg_index) { + const char *error = 0; + const Arg *arg = arg_index == UINT_MAX ? + next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); + if (error) + throw FormatError(!*s ? "invalid format string" : error); + return *arg; +} + template unsigned fmt::internal::PrintfFormatter::parse_header( const Char *&s, FormatSpec &spec) { diff --git a/format.h b/format.h index 2a9e140c..69acecd3 100644 --- a/format.h +++ b/format.h @@ -846,11 +846,11 @@ protected: ArgList args_; int next_arg_index_; - const Arg &next_arg(const char *&error); + // Returns the next argument. + 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); + // Returns the argument with specified index. + const Arg *get_arg(unsigned arg_index, const char *&error); template void write(BasicWriter &w, const Char *start, const Char *end) { @@ -865,16 +865,14 @@ class PrintfFormatter : private FormatterBase { private: void parse_flags(FormatSpec &spec, const Char *&s); + // Returns the argument with specified index or, if arg_index is equal + // to the maximum unsigned value, the next argument. + const Arg &get_arg(const Char *s, + unsigned arg_index = std::numeric_limits::max()); + // Parses argument index, flags and width and returns the argument index. unsigned parse_header(const Char *&s, FormatSpec &spec); - const Arg &get_arg(const Char *s, - unsigned arg_index = std::numeric_limits::max()) { - if (!*s) - throw FormatError("invalid format string"); - return handle_arg_index(arg_index); - } - public: void format(BasicWriter &writer, BasicStringRef format, const ArgList &args);