Do not pass empty format_str to UDT formatters

This commit is contained in:
Fred Miller 2020-07-14 23:08:51 +08:00
parent c108ee1d59
commit d329abc7cb
5 changed files with 19 additions and 12 deletions

View File

@ -94,7 +94,7 @@ template <typename Char> struct part_counter {
return ++num_parts, 0;
}
FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
FMT_CONSTEXPR void on_replacement_field(int, const Char*, const Char*) {}
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
const Char* end) {
@ -160,7 +160,7 @@ class format_string_compiler : public error_handler {
return 0;
}
FMT_CONSTEXPR void on_replacement_field(int, const Char* ptr) {
FMT_CONSTEXPR void on_replacement_field(int, const Char* ptr, const Char*) {
part_.arg_id_end = ptr;
handler_(part_);
}

View File

@ -1826,6 +1826,7 @@ template <typename OutputIt, typename Char> struct default_arg_formatter {
using context = basic_format_context<OutputIt, Char>;
OutputIt out;
basic_string_view<Char> format_str;
basic_format_args<context> args;
locale_ref loc;
@ -1834,7 +1835,7 @@ template <typename OutputIt, typename Char> struct default_arg_formatter {
}
OutputIt operator()(typename basic_format_arg<context>::handle handle) {
basic_format_parse_context<Char> parse_ctx({});
basic_format_parse_context<Char> parse_ctx(format_str);
basic_format_context<OutputIt, Char> format_ctx(out, args, loc);
handle.format(parse_ctx, format_ctx);
return format_ctx.out();
@ -2629,7 +2630,7 @@ FMT_CONSTEXPR const Char* parse_replacement_field(const Char* begin,
++begin;
if (begin == end) return handler.on_error("invalid format string"), end;
if (static_cast<char>(*begin) == '}') {
handler.on_replacement_field(handler.on_arg_id(), begin);
handler.on_replacement_field(handler.on_arg_id(), begin, end);
} else if (*begin == '{') {
handler.on_text(begin, begin + 1);
} else {
@ -2637,7 +2638,7 @@ FMT_CONSTEXPR const Char* parse_replacement_field(const Char* begin,
begin = parse_arg_id(begin, end, adapter);
Char c = begin != end ? *begin : Char();
if (c == '}') {
handler.on_replacement_field(adapter.arg_id, begin);
handler.on_replacement_field(adapter.arg_id, begin, end);
} else if (c == ':') {
begin = handler.on_format_specs(adapter.arg_id, begin + 1, end);
if (begin == end || *begin != '}')
@ -2740,11 +2741,15 @@ struct format_handler : detail::error_handler {
return arg_id;
}
FMT_INLINE void on_replacement_field(int id, const Char*) {
FMT_INLINE void on_replacement_field(int id, const Char* begin,
const Char* end) {
auto arg = get_arg(context, id);
context.advance_to(visit_format_arg(
default_arg_formatter<typename ArgFormatter::iterator, Char>{
context.out(), context.args(), context.locale()},
context.out(),
{begin, static_cast<size_t>(end - begin)},
context.args(),
context.locale()},
arg));
}
@ -2814,7 +2819,7 @@ class format_string_checker {
return 0;
}
FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
FMT_CONSTEXPR void on_replacement_field(int, const Char*, const Char*) {}
FMT_CONSTEXPR const Char* on_format_specs(int id, const Char* begin,
const Char*) {
@ -3303,7 +3308,9 @@ typename Context::iterator vformat_to(
if (!arg) detail::error_handler().on_error("argument not found");
using iterator = typename ArgFormatter::iterator;
return visit_format_arg(
detail::default_arg_formatter<iterator, Char>{out, args, loc}, arg);
detail::default_arg_formatter<iterator, Char>{out, format_str, args,
loc},
arg);
}
detail::format_handler<ArgFormatter, Char, Context> h(out, format_str, args,
loc);

View File

@ -600,7 +600,7 @@ struct format_handler : detail::error_handler {
int on_arg_id(unsigned id) { return parse_ctx.check_arg_id(id), id; }
int on_arg_id(fmt::basic_string_view<Char>) { return 0; }
void on_replacement_field(int id, const Char* p) {
void on_replacement_field(int id, const Char* p, const Char*) {
auto arg = context.arg(id);
parse_ctx.advance_to(parse_ctx.begin() + (p - &*parse_ctx.begin()));
custom_formatter<Context> f(parse_ctx, context);

View File

@ -2246,7 +2246,7 @@ struct test_format_string_handler {
template <typename T> FMT_CONSTEXPR int on_arg_id(T) { return 0; }
FMT_CONSTEXPR void on_replacement_field(int, const char*) {}
FMT_CONSTEXPR void on_replacement_field(int, const char*, const char*) {}
FMT_CONSTEXPR const char* on_format_specs(int, const char* begin,
const char*) {

View File

@ -177,7 +177,7 @@ struct scan_handler : error_handler {
}
int on_arg_id(string_view) { return on_error("invalid format"), 0; }
void on_replacement_field(int, const char*) {
void on_replacement_field(int, const char*, const char*) {
auto it = scan_ctx_.begin(), end = scan_ctx_.end();
switch (arg_.type) {
case scan_type::int_type: