From 8b86a74ad5988be4dcefecfc794e2b79f94624ab Mon Sep 17 00:00:00 2001 From: vitaut Date: Mon, 9 Nov 2015 07:17:36 -0800 Subject: [PATCH] Allow formatting C strings as pointers (#223) --- format.cc | 19 ++++++++++++++++--- format.h | 10 +++++----- test/format-test.cc | 2 +- test/printf-test.cc | 2 ++ test/util-test.cc | 1 + 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/format.cc b/format.cc index 8e23701d..2168ce6f 100644 --- a/format.cc +++ b/format.cc @@ -409,6 +409,12 @@ class BasicArgFormatter : public ArgVisitor { FMT_DISALLOW_COPY_AND_ASSIGN(BasicArgFormatter); + void write_pointer(const void *p) { + spec_.flags_ = HASH_FLAG; + spec_.type_ = 'x'; + writer_.write_int(reinterpret_cast(p), spec_); + } + protected: BasicWriter &writer() { return writer_; } const FormatSpec &spec() const { return spec_; } @@ -462,6 +468,15 @@ class BasicArgFormatter : public ArgVisitor { *out = internal::CharTraits::cast(value); } + void visit_cstring(const char *value) { + if (spec_.type_ == 'p') { + write_pointer(value); + return; + } + Arg::StringValue str = {value, 0}; + writer_.write_str(str, spec_); + } + void visit_string(Arg::StringValue value) { writer_.write_str(value, spec_); } @@ -475,9 +490,7 @@ class BasicArgFormatter : public ArgVisitor { void visit_pointer(const void *value) { if (spec_.type_ && spec_.type_ != 'p') report_unknown_type(spec_.type_, "pointer"); - spec_.flags_ = HASH_FLAG; - spec_.type_ = 'x'; - writer_.write_int(reinterpret_cast(value), spec_); + write_pointer(value); } }; diff --git a/format.h b/format.h index ed2073be..eb4a86c1 100644 --- a/format.h +++ b/format.h @@ -1186,6 +1186,9 @@ class ArgVisitor { return FMT_DISPATCH(visit_unhandled_arg()); } + Result visit_cstring(const char *) { + return FMT_DISPATCH(visit_unhandled_arg()); + } Result visit_string(Arg::StringValue) { return FMT_DISPATCH(visit_unhandled_arg()); } @@ -1220,11 +1223,8 @@ class ArgVisitor { return FMT_DISPATCH(visit_double(arg.double_value)); case Arg::LONG_DOUBLE: return FMT_DISPATCH(visit_long_double(arg.long_double_value)); - case Arg::CSTRING: { - Arg::StringValue str = arg.string; - str.size = 0; - return FMT_DISPATCH(visit_string(str)); - } + case Arg::CSTRING: + return FMT_DISPATCH(visit_cstring(arg.string.value)); case Arg::STRING: return FMT_DISPATCH(visit_string(arg.string)); case Arg::WSTRING: diff --git a/test/format-test.cc b/test/format-test.cc index aa85d234..f2df51ea 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1336,7 +1336,7 @@ TEST(FormatterTest, FormatWChar) { } TEST(FormatterTest, FormatCString) { - check_unknown_types("test", "s", "string"); + check_unknown_types("test", "sp", "string"); EXPECT_EQ("test", format("{0}", "test")); EXPECT_EQ("test", format("{0:s}", "test")); char nonconst[] = "nonconst"; diff --git a/test/printf-test.cc b/test/printf-test.cc index 0e615740..8f8647f0 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -425,6 +425,8 @@ TEST(PrintfTest, Pointer) { int n; void *p = &n; EXPECT_PRINTF(fmt::format("{}", p), "%p", p); + const char *s = "test"; + EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s); } TEST(PrintfTest, Custom) { diff --git a/test/util-test.cc b/test/util-test.cc index 6736c80f..04c38844 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -593,6 +593,7 @@ struct TestVisitor : fmt::internal::ArgVisitor { Result visit_double(double value) { return value; } Result visit_long_double(long double value) { return value; } Result visit_char(int value) { return static_cast(value); } + Result visit_cstring(const char *s) { return s; } Result visit_string(Arg::StringValue s) { return s.value; } Result visit_wstring(Arg::StringValue s) { return s.value; } Result visit_pointer(const void *p) { return p; }