From 1f19b986a0d408679a0712f58b2a6f501e527b40 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 16 Jun 2014 07:49:30 -0700 Subject: [PATCH] Implement printf specifications. --- format.cc | 74 ++++++++++++++++++++++++++++++------------------------- format.h | 1 + 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/format.cc b/format.cc index b7138985..df031371 100644 --- a/format.cc +++ b/format.cc @@ -625,6 +625,33 @@ void fmt::BasicWriter::PrintfParser::ParseFlags( } } +template +unsigned fmt::BasicWriter::PrintfParser::ParseArgIndex( + const Char *&s, const char *&error) { + Char c = *s; + unsigned value = 0; + if (c >= '0' && c <= '9') { + value = internal::ParseNonnegativeInt(s, error); + if (*s == '$') { + ++s; + if (next_arg_index_ <= 0) { + next_arg_index_ = -1; + return value - 1; + } + if (!error) + error = "cannot switch from automatic to manual argument indexing"; + } + } + if (next_arg_index_ >= 0) + return next_arg_index_++; + // Don't check if the error has already been set because the argument + // index is semantically the first part of the format string, so + // indexing errors are reported first even though parsing width + // above can cause another error. + error = "cannot switch from manual to automatic argument indexing"; + return value; +} + template void fmt::BasicWriter::PrintfParser::Format( BasicWriter &writer, BasicStringRef format, @@ -659,37 +686,14 @@ void fmt::BasicWriter::PrintfParser::Format( // is OK for both cases. const char *error = 0; - unsigned arg_index = 0; - bool have_arg_index = false; c = *s; - if (c >= '0' && c <= '9') { - unsigned value = internal::ParseNonnegativeInt(s, error); - if (*s != '$') { - if (c == '0') - spec.fill_ = '0'; - if (value != 0) - spec.width_ = value; - } else { - ++s; - if (next_arg_index_ <= 0) { - have_arg_index = true; - next_arg_index_ = -1; - arg_index = value - 1; - } else if (!error) { - error = "cannot switch from automatic to manual argument indexing"; - } - } - } - if (!have_arg_index) { - if (next_arg_index_ >= 0) { - arg_index = next_arg_index_++; - } else { - // We don't check if error has already been set because argument - // index is semantically the first part of the format string, so - // indexing errors are reported first even though parsing width - // above can cause another error. - error = "cannot switch from manual to automatic argument indexing"; - } + unsigned arg_index = ParseArgIndex(s, error); + if (c >= '0' && c <= '9' && s[-1] != '$') { // TODO + if (c == '0') + spec.fill_ = '0'; + if (arg_index != 0) + spec.width_ = arg_index + 1; + arg_index = 0; } const ArgInfo *arg = 0; @@ -708,11 +712,13 @@ void fmt::BasicWriter::PrintfParser::Format( ParseFlags(spec, s, *arg); // Parse width and zero flag. - if (*s < '0' || *s > '9') { - // TODO: parse '*' width + if (*s >= '0' && *s <= '9') { + spec.width_ = internal::ParseNonnegativeInt(s, error); + } else if (*s == '*') { + ++s; + // TODO: parse arg index + } else break; - } - spec.width_ = internal::ParseNonnegativeInt(s, error); } // Fall through. default: diff --git a/format.h b/format.h index 42b0e65f..6d37ec96 100644 --- a/format.h +++ b/format.h @@ -1039,6 +1039,7 @@ class BasicWriter { const ArgInfo *args_; int next_arg_index_; + unsigned ParseArgIndex(const Char *&s, const char *&error); void ParseFlags(FormatSpec &spec, const Char *&s, const ArgInfo &arg); public: