Allow formatting C strings as pointers (#223)
This commit is contained in:
parent
7c24973637
commit
8b86a74ad5
19
format.cc
19
format.cc
@ -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_; }
|
||||
@ -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_);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
10
format.h
10
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<char>) {
|
||||
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<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:
|
||||
|
@ -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";
|
||||
|
@ -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) {
|
||||
|
@ -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; }
|
||||
|
Loading…
Reference in New Issue
Block a user