Skip to content

Commit

Permalink
Allow formatting C strings as pointers (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Nov 9, 2015
1 parent 7c24973 commit 8b86a74
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 9 deletions.
19 changes: 16 additions & 3 deletions format.cc
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,12 @@ class BasicArgFormatter : public ArgVisitor<Impl, void> {

FMT_DISALLOW_COPY_AND_ASSIGN(BasicArgFormatter);

void write_pointer(const void *p) {
spec_.flags_ = HASH_FLAG;
spec_.type_ = 'x';
writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
}

protected:
BasicWriter<Char> &writer() { return writer_; }
const FormatSpec &spec() const { return spec_; }
Expand Down Expand Up @@ -462,6 +468,15 @@ class BasicArgFormatter : public ArgVisitor<Impl, void> {
*out = internal::CharTraits<Char>::cast(value);
}

void visit_cstring(const char *value) {
if (spec_.type_ == 'p') {
write_pointer(value);
return;
}
Arg::StringValue<char> str = {value, 0};
writer_.write_str(str, spec_);
}

void visit_string(Arg::StringValue<char> value) {
writer_.write_str(value, spec_);
}
Expand All @@ -475,9 +490,7 @@ class BasicArgFormatter : public ArgVisitor<Impl, void> {
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<uintptr_t>(value), spec_);
write_pointer(value);
}
};

Expand Down
10 changes: 5 additions & 5 deletions format.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<char>) {
return FMT_DISPATCH(visit_unhandled_arg());
}
Expand Down Expand Up @@ -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<char> 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:
Expand Down
2 changes: 1 addition & 1 deletion test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
2 changes: 2 additions & 0 deletions test/printf-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions test/util-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ struct TestVisitor : fmt::internal::ArgVisitor<TestVisitor, Result> {
Result visit_double(double value) { return value; }
Result visit_long_double(long double value) { return value; }
Result visit_char(int value) { return static_cast<char>(value); }
Result visit_cstring(const char *s) { return s; }
Result visit_string(Arg::StringValue<char> s) { return s.value; }
Result visit_wstring(Arg::StringValue<wchar_t> s) { return s.value; }
Result visit_pointer(const void *p) { return p; }
Expand Down

0 comments on commit 8b86a74

Please sign in to comment.