Use textual formatting for bool with %s specifier in printf (#224)

This commit is contained in:
vitaut 2015-11-13 07:18:44 -08:00
parent 7dcf05108e
commit 2157375d5c
2 changed files with 30 additions and 12 deletions

View File

@ -354,6 +354,11 @@ class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> {
ArgConverter(fmt::internal::Arg &arg, wchar_t type) ArgConverter(fmt::internal::Arg &arg, wchar_t type)
: arg_(arg), type_(type) {} : arg_(arg), type_(type) {}
void visit_bool(bool value) {
if (type_ != 's')
visit_any_int(value);
}
template <typename U> template <typename U>
void visit_any_int(U value) { void visit_any_int(U value) {
bool is_signed = type_ == 'd' || type_ == 'i'; bool is_signed = type_ == 'd' || type_ == 'i';
@ -418,7 +423,13 @@ class BasicArgFormatter : public ArgVisitor<Impl, void> {
protected: protected:
BasicWriter<Char> &writer() { return writer_; } BasicWriter<Char> &writer() { return writer_; }
const FormatSpec &spec() const { return spec_; } FormatSpec &spec() { return spec_; }
void write_bool(bool value) {
const char *str_value = value ? "true" : "false";
Arg::StringValue<char> str = { str_value, strlen(str_value) };
writer_.write_str(str, spec_);
}
public: public:
BasicArgFormatter(BasicWriter<Char> &w, FormatSpec &s) BasicArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
@ -431,13 +442,9 @@ class BasicArgFormatter : public ArgVisitor<Impl, void> {
void visit_any_double(T value) { writer_.write_double(value, spec_); } void visit_any_double(T value) { writer_.write_double(value, spec_); }
void visit_bool(bool value) { void visit_bool(bool value) {
if (spec_.type_) { if (spec_.type_)
writer_.write_int(value, spec_); return visit_any_int(value);
return; write_bool(value);
}
const char *str_value = value ? "true" : "false";
Arg::StringValue<char> str = { str_value, strlen(str_value) };
writer_.write_str(str, spec_);
} }
void visit_char(int value) { void visit_char(int value) {
@ -470,10 +477,8 @@ class BasicArgFormatter : public ArgVisitor<Impl, void> {
} }
void visit_cstring(const char *value) { void visit_cstring(const char *value) {
if (spec_.type_ == 'p') { if (spec_.type_ == 'p')
write_pointer(value); return write_pointer(value);
return;
}
Arg::StringValue<char> str = {value, 0}; Arg::StringValue<char> str = {value, 0};
writer_.write_str(str, spec_); writer_.write_str(str, spec_);
} }
@ -524,6 +529,14 @@ class PrintfArgFormatter :
PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s) PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
: BasicArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {} : BasicArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {}
void visit_bool(bool value) {
FormatSpec &fmt_spec = this->spec();
if (fmt_spec.type_ != 's')
return this->visit_any_int(value);
fmt_spec.type_ = 0;
this->write_bool(value);
}
void visit_char(int value) { void visit_char(int value) {
const FormatSpec &fmt_spec = this->spec(); const FormatSpec &fmt_spec = this->spec();
BasicWriter<Char> &w = this->writer(); BasicWriter<Char> &w = this->writer();

View File

@ -373,6 +373,11 @@ TEST(PrintfTest, Length) {
EXPECT_PRINTF(fmt::format("{}", max), "%Lg", max); EXPECT_PRINTF(fmt::format("{}", max), "%Lg", max);
} }
TEST(PrintfTest, Bool) {
EXPECT_PRINTF("1", "%d", true);
EXPECT_PRINTF("true", "%s", true);
}
TEST(PrintfTest, Int) { TEST(PrintfTest, Int) {
EXPECT_PRINTF("-42", "%d", -42); EXPECT_PRINTF("-42", "%d", -42);
EXPECT_PRINTF("-42", "%i", -42); EXPECT_PRINTF("-42", "%i", -42);