Add String::format variant that takes va_args
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Aug 2017 20:23:57 +0000 (20:23 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Aug 2017 20:23:57 +0000 (20:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175988

Reviewed by Jer Noble.

Source/WTF:

* wtf/text/WTFString.cpp:
(WTF::createWithFormatAndArguments): Created with the guts of String::format.
(WTF::String::formatWithArguments): New, call createWithFormatAndArguments.
(WTF::String::format): Move logic to createWithFormatAndArguments, use it.
* wtf/text/WTFString.h:

Tools:

* TestWebKitAPI/Tests/WTF/WTFString.cpp:
(TestWebKitAPI::testWithFormatAndArguments):
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221203 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/text/WTFString.cpp
Source/WTF/wtf/text/WTFString.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp

index 667f30fd49527c8d8ffbe7867b8cdc53bf417550..59601f27d18262acdd42b48f616a1f739bf0e1a1 100644 (file)
@@ -1,3 +1,16 @@
+2017-08-25  Eric Carlson  <eric.carlson@apple.com>
+
+        Add String::format variant that takes va_args
+        https://bugs.webkit.org/show_bug.cgi?id=175988
+
+        Reviewed by Jer Noble.
+
+        * wtf/text/WTFString.cpp:
+        (WTF::createWithFormatAndArguments): Created with the guts of String::format.
+        (WTF::String::formatWithArguments): New, call createWithFormatAndArguments.
+        (WTF::String::format): Move logic to createWithFormatAndArguments, use it.
+        * wtf/text/WTFString.h:
+
 2017-08-25  Saam Barati  <sbarati@apple.com>
 
         Support compiling catch in the DFG
index dbe6eeab171687d952a0b15efe76afab3703107f..b6ee04ad14f2776598db16f74ae759cfba3b1d39 100644 (file)
@@ -465,23 +465,21 @@ Vector<UChar> String::charactersWithNullTermination() const
     return result;
 }
 
-String String::format(const char *format, ...)
+static String createWithFormatAndArguments(const char *format, va_list args)
 {
-    va_list args;
-    va_start(args, format);
-
-#if USE(CF) && !OS(WINDOWS)
-    if (strstr(format, "%@")) {
-        RetainPtr<CFStringRef> cfFormat = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, format, kCFStringEncodingUTF8));
+    va_list argsCopy;
+    va_copy(argsCopy, args);
 
 #if COMPILER(CLANG)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat-nonliteral"
 #endif
+
+#if USE(CF) && !OS(WINDOWS)
+    if (strstr(format, "%@")) {
+        RetainPtr<CFStringRef> cfFormat = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, format, kCFStringEncodingUTF8));
+
         RetainPtr<CFStringRef> result = adoptCF(CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, nullptr, cfFormat.get(), args));
-#if COMPILER(CLANG)
-#pragma clang diagnostic pop
-#endif
 
         va_end(args);
         return result.get();
@@ -505,14 +503,31 @@ String String::format(const char *format, ...)
     Vector<char, 256> buffer;
     unsigned len = result;
     buffer.grow(len + 1);
-    
-    va_start(args, format);
+
     // Now do the formatting again, guaranteed to fit.
-    vsnprintf(buffer.data(), buffer.size(), format, args);
+    vsnprintf(buffer.data(), buffer.size(), format, argsCopy);
+    va_end(argsCopy);
+
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
 
+    return StringImpl::create(reinterpret_cast<const LChar*>(buffer.data()), len);
+}
+
+String String::formatWithArguments(const char *format, va_list args)
+{
+    return createWithFormatAndArguments(format, args);
+}
+
+String String::format(const char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    String result = createWithFormatAndArguments(format, args);
     va_end(args);
     
-    return StringImpl::create(reinterpret_cast<const LChar*>(buffer.data()), len);
+    return result;
 }
 
 String String::number(int number)
index 83d6628020039f1a5704f85905d80e390cf4216b..2a6732244b2af3c1225d5637ce846b5cdf9fcd5e 100644 (file)
@@ -25,6 +25,7 @@
 // This file would be called String.h, but that conflicts with <string.h>
 // on systems without case-sensitive file systems.
 
+#include <stdarg.h>
 #include <wtf/Function.h>
 #include <wtf/text/ASCIIFastPath.h>
 #include <wtf/text/IntegerToStringConversion.h>
@@ -353,6 +354,7 @@ public:
     WTF_EXPORT_STRING_API String foldCase() const;
 
     WTF_EXPORT_STRING_API static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
+    WTF_EXPORT_STRING_API static String formatWithArguments(const char *, va_list) WTF_ATTRIBUTE_PRINTF(1, 0);
 
     // Returns an uninitialized string. The characters needs to be written
     // into the buffer returned in data before the returned string is used.
index 2c1a3b20afe2a198c58b5f8e8596508615f153a3..cf118b32a3e76b7eb38ef35092be50a8fdf8043f 100644 (file)
@@ -1,3 +1,14 @@
+2017-08-25  Eric Carlson  <eric.carlson@apple.com>
+
+        Add String::format variant that takes va_args
+        https://bugs.webkit.org/show_bug.cgi?id=175988
+
+        Reviewed by Jer Noble.
+
+        * TestWebKitAPI/Tests/WTF/WTFString.cpp:
+        (TestWebKitAPI::testWithFormatAndArguments):
+        (TestWebKitAPI::TEST):
+
 2017-08-25  Jonathan Bedard  <jbedard@apple.com>
 
         Follow-up Internal build fix for r221187
index c7140681603e4414bf68b9e72acaeccc87459044..6184c6232bbf425770b744992b6463cafba9ef1e 100644 (file)
@@ -362,4 +362,43 @@ TEST(WTF, StringReverseFindBasic)
     EXPECT_EQ(reference.reverseFind('c', 4), notFound);
 }
 
+WTF_ATTRIBUTE_PRINTF(2, 3)
+static void testWithFormatAndArguments(const char* expected, const char* format, ...)
+{
+    va_list arguments;
+    va_start(arguments, format);
+
+#if COMPILER(GCC_OR_CLANG)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#endif
+    String result = String::formatWithArguments(format, arguments);
+#if COMPILER(GCC_OR_CLANG)
+#pragma GCC diagnostic pop
+#endif
+
+    va_end(arguments);
+
+    EXPECT_STREQ(expected, result.utf8().data());
+}
+
+TEST(WTF, StringFormatWithArguments)
+{
+    testWithFormatAndArguments("hello cruel world", "%s %s %s", "hello", "cruel" , "world");
+
+    testWithFormatAndArguments("hello 17890 world", "%s%u%s", "hello ", 17890u, " world");
+
+    testWithFormatAndArguments("hello 17890.000 world", "%s %.3f %s", "hello", 17890.0f, "world");
+    testWithFormatAndArguments("hello 17890.50 world", "%s %.2f %s", "hello", 17890.5f, "world");
+
+    testWithFormatAndArguments("hello -17890 world", "%s %.0f %s", "hello", -17890.0f, "world");
+    testWithFormatAndArguments("hello -17890.5 world", "%s %.1f %s", "hello", -17890.5f, "world");
+
+    testWithFormatAndArguments("hello 17890 world", "%s %.0f %s", "hello", 17890.0, "world");
+    testWithFormatAndArguments("hello 17890.5 world", "%s %.1f %s", "hello", 17890.5, "world");
+
+    testWithFormatAndArguments("hello -17890 world", "%s %.0f %s", "hello", -17890.0, "world");
+    testWithFormatAndArguments("hello -17890.5 world", "%s %.1f %s", "hello", -17890.5, "world");
+}
+
 } // namespace TestWebKitAPI