From ef710dee6c8ae85f9fd6689d391a25aac159cc7c Mon Sep 17 00:00:00 2001 From: vitaut Date: Fri, 18 Sep 2015 16:26:41 -0700 Subject: [PATCH] Add sprintf overload for wide strings and fix an issue in formatting user-defined objects. Thanks to @ScottLangham --- format.cc | 3 ++- format.h | 7 +++++++ test/printf-test.cc | 4 ++++ test/util.h | 18 ++++++++++++++---- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/format.cc b/format.cc index 62b54d6d..a9c978b9 100644 --- a/format.cc +++ b/format.cc @@ -526,7 +526,8 @@ class PrintfArgFormatter : void visit_custom(Arg::CustomValue c) { BasicFormatter formatter(ArgList(), this->writer()); - const char *format = "}"; + const Char format_str[] = {'}', 0}; + const Char *format = format_str; c.format(&formatter, c.value, &format); } }; diff --git a/format.h b/format.h index 4bc47bfa..8260024f 100644 --- a/format.h +++ b/format.h @@ -2706,6 +2706,12 @@ inline std::string sprintf(CStringRef format, ArgList args) { return w.str(); } +inline std::wstring sprintf(WCStringRef format, ArgList args) { + WMemoryWriter w; + printf(w, format, args); + return w.str(); +} + /** \rst Prints formatted data to the file *f*. @@ -2994,6 +3000,7 @@ FMT_VARIADIC(void, print, std::FILE *, CStringRef) FMT_VARIADIC(void, print, std::ostream &, CStringRef) FMT_VARIADIC(void, print_colored, Color, CStringRef) FMT_VARIADIC(std::string, sprintf, CStringRef) +FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) FMT_VARIADIC(int, printf, CStringRef) FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) } diff --git a/test/printf-test.cc b/test/printf-test.cc index e942d6fe..041fbad1 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -456,3 +456,7 @@ TEST(PrintfTest, PrintfError) { EXPECT_LT(result, 0); } #endif + +TEST(PrintfTest, WideString) { + EXPECT_EQ(L"abc", fmt::sprintf(L"%s", TestWString(L"abc"))); +} diff --git a/test/util.h b/test/util.h index 0b41fbbb..7f42cecd 100644 --- a/test/util.h +++ b/test/util.h @@ -68,15 +68,25 @@ inline FILE *safe_fopen(const char *filename, const char *mode) { #endif } -class TestString { +template +class BasicTestString { private: - std::string value_; + std::basic_string value_; + + static const Char EMPTY[]; public: - explicit TestString(const char *value = "") : value_(value) {} + explicit BasicTestString(const Char *value = EMPTY) : value_(value) {} - friend std::ostream &operator<<(std::ostream &os, const TestString &s) { + friend std::basic_ostream &operator<<( + std::basic_ostream &os, const BasicTestString &s) { os << s.value_; return os; } }; + +template +const Char BasicTestString::EMPTY[] = {0}; + +typedef BasicTestString TestString; +typedef BasicTestString TestWString;