Commit 271fa8c9 authored by Victor Zverovich's avatar Victor Zverovich

Improve handling of format strings in custom arguments.

parent 3947a7a9
...@@ -175,19 +175,6 @@ int parse_nonnegative_int(const Char *&s) { ...@@ -175,19 +175,6 @@ int parse_nonnegative_int(const Char *&s) {
return value; return value;
} }
template <typename Char>
const Char *find_closing_brace(const Char *s, int num_open_braces = 1) {
for (int n = num_open_braces; *s; ++s) {
if (*s == '{') {
++n;
} else if (*s == '}') {
if (--n == 0)
return s;
}
}
throw fmt::FormatError("unmatched '{' in format");
}
template <typename Char> template <typename Char>
void check_sign(const Char *&s, const Arg &arg) { void check_sign(const Char *&s, const Arg &arg) {
char sign = static_cast<char>(*s); char sign = static_cast<char>(*s);
...@@ -574,7 +561,7 @@ class fmt::internal::ArgFormatter : ...@@ -574,7 +561,7 @@ class fmt::internal::ArgFormatter :
} }
void visit_custom(Arg::CustomValue c) { void visit_custom(Arg::CustomValue c) {
c.format(&formatter_, c.value, format_); c.format(&formatter_, c.value, &format_);
} }
}; };
...@@ -1019,11 +1006,13 @@ void fmt::internal::PrintfFormatter<Char>::format( ...@@ -1019,11 +1006,13 @@ void fmt::internal::PrintfFormatter<Char>::format(
spec.type_ = 'x'; spec.type_ = 'x';
writer.write_int(reinterpret_cast<uintptr_t>(arg.pointer_value), spec); writer.write_int(reinterpret_cast<uintptr_t>(arg.pointer_value), spec);
break; break;
case Arg::CUSTOM: case Arg::CUSTOM: {
if (spec.type_) if (spec.type_)
internal::report_unknown_type(spec.type_, "object"); internal::report_unknown_type(spec.type_, "object");
arg.custom.format(&writer, arg.custom.value, "s"); const void *s = "s";
arg.custom.format(&writer, arg.custom.value, &s);
break; break;
}
default: default:
assert(false); assert(false);
break; break;
...@@ -1034,14 +1023,14 @@ void fmt::internal::PrintfFormatter<Char>::format( ...@@ -1034,14 +1023,14 @@ void fmt::internal::PrintfFormatter<Char>::format(
template <typename Char> template <typename Char>
const Char *fmt::BasicFormatter<Char>::format( const Char *fmt::BasicFormatter<Char>::format(
const Char *format_str, const Arg &arg) { const Char *&format_str, const Arg &arg) {
const Char *s = format_str; const Char *s = format_str;
const char *error = 0; const char *error = 0;
FormatSpec spec; FormatSpec spec;
if (*s == ':') { if (*s == ':') {
if (arg.type == Arg::CUSTOM) { if (arg.type == Arg::CUSTOM) {
arg.custom.format(this, arg.custom.value, s); arg.custom.format(this, arg.custom.value, &s);
return find_closing_brace(s) + 1; return s;
} }
++s; ++s;
// Parse fill and alignment. // Parse fill and alignment.
......
...@@ -132,7 +132,7 @@ template <typename Char> ...@@ -132,7 +132,7 @@ template <typename Char>
class BasicFormatter; class BasicFormatter;
template <typename Char, typename T> template <typename Char, typename T>
void format(BasicFormatter<Char> &f, const Char *format_str, const T &value); void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value);
/** /**
\rst \rst
...@@ -583,7 +583,7 @@ struct Arg { ...@@ -583,7 +583,7 @@ struct Arg {
}; };
typedef void (*FormatFunc)( typedef void (*FormatFunc)(
void *formatter, const void *arg, const void *format_str); void *formatter, const void *arg, void *format_str_ptr);
struct CustomValue { struct CustomValue {
const void *value; const void *value;
...@@ -634,9 +634,9 @@ class MakeArg : public Arg { ...@@ -634,9 +634,9 @@ class MakeArg : public Arg {
// Formats an argument of a custom type, such as a user-defined class. // Formats an argument of a custom type, such as a user-defined class.
template <typename T> template <typename T>
static void format_custom_arg( static void format_custom_arg(
void *formatter, const void *arg, const void *format_str) { void *formatter, const void *arg, void *format_str_ptr) {
format(*static_cast<BasicFormatter<Char>*>(formatter), format(*static_cast<BasicFormatter<Char>*>(formatter),
static_cast<const Char*>(format_str), *static_cast<const T*>(arg)); *static_cast<const Char**>(format_str_ptr), *static_cast<const T*>(arg));
} }
public: public:
...@@ -896,7 +896,7 @@ public: ...@@ -896,7 +896,7 @@ public:
void format(BasicStringRef<Char> format_str, const ArgList &args); void format(BasicStringRef<Char> format_str, const ArgList &args);
const Char *format(const Char *format_str, const internal::Arg &arg); const Char *format(const Char *&format_str, const internal::Arg &arg);
}; };
enum Alignment { enum Alignment {
...@@ -1681,10 +1681,10 @@ void BasicWriter<Char>::write_int(T value, const Spec &spec) { ...@@ -1681,10 +1681,10 @@ void BasicWriter<Char>::write_int(T value, const Spec &spec) {
// Formats a value. // Formats a value.
template <typename Char, typename T> template <typename Char, typename T>
void format(BasicFormatter<Char> &f, const Char *format_str, const T &value) { void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {
std::basic_ostringstream<Char> os; std::basic_ostringstream<Char> os;
os << value; os << value;
f.format(format_str, internal::MakeArg<Char>(os.str())); format_str = f.format(format_str, internal::MakeArg<Char>(os.str()));
} }
// Reports a system error without throwing an exception. // Reports a system error without throwing an exception.
......
...@@ -238,7 +238,8 @@ TEST(ArgTest, MakeArg) { ...@@ -238,7 +238,8 @@ TEST(ArgTest, MakeArg) {
EXPECT_EQ(&t, arg.custom.value); EXPECT_EQ(&t, arg.custom.value);
fmt::Writer w; fmt::Writer w;
fmt::BasicFormatter<char> formatter(w); fmt::BasicFormatter<char> formatter(w);
arg.custom.format(&formatter, &t, "}"); const char *s = "}";
arg.custom.format(&formatter, &t, &s);
EXPECT_EQ("test", w.str()); EXPECT_EQ("test", w.str());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment