Commit 4d900d1a authored by Bryce Seager van Dyk's avatar Bryce Seager van Dyk
Browse files

Bug 1673670 - Add vprintf style ctor for nsPrintfCString + tests. r=xpcom-reviewers,sg

parent 36ba3257
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -15,6 +15,18 @@
 *
 *   NS_WARNING(nsPrintfCString("Unexpected value: %f", 13.917).get());
 *
 * nsPrintfCString also allows for vprintf like calling. This is useful for
 * functions that have already received variadic arguments and want to create
 * a nsPrintfCString. For example:
 *
 * void LogToSeveralLocations(const char* aFormat,...) {
 *   va_list ap;
 *   va_start(ap, aFormat);
 *   nsPrintfCString logString(aFormat, ap);
 *   va_end(ap);
 *   // Use logString
 *  }
 *
 * nsPrintfCString has a small built-in auto-buffer.  For larger strings, it
 * will allocate on the heap.
 *
@@ -31,6 +43,11 @@ class nsPrintfCString : public nsAutoCStringN<16> {
    AppendPrintf(aFormat, ap);
    va_end(ap);
  }

  nsPrintfCString(const char_type* aFormat, va_list aArgs)
      MOZ_FORMAT_PRINTF(2, 0) {
    AppendPrintf(aFormat, aArgs);
  }
};

#endif  // !defined(nsPrintfCString_h___)
+64 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "nsASCIIMask.h"
#include "nsPrintfCString.h"
#include "nsString.h"
#include "nsStringBuffer.h"
#include "nsReadableUtils.h"
@@ -1968,6 +1969,69 @@ TEST_F(Strings, ConvertToSpan) {
  }
}

TEST_F(Strings, printf_string) {
  auto getStringViaVprintfCtor = [](const char* aFormat, ...) {
    // Ensures creation of an nsPrintfCString via the vprintf style ctor.
    va_list ap;
    va_start(ap, aFormat);
    const nsPrintfCString string(aFormat, ap);
    va_end(ap);
    return string;
  };

  {
    const char* format = "Characters %c %%";
    const char* expectedOutput = "Characters B %";
    const nsPrintfCString printfString(format, 'B');
    const nsPrintfCString vprintfString(getStringViaVprintfCtor(format, 'B'));
    EXPECT_TRUE(printfString.Equals(vprintfString))
        << printfString.get() << " != " << vprintfString.get();
    EXPECT_TRUE(printfString.EqualsASCII(expectedOutput))
        << printfString.get() << " != " << expectedOutput;
  }

  {
    const char* format = "Strings %s %s";
    const char* expectedOutput = "Strings foo bar";
    const nsPrintfCString printfString(format, "foo", "bar");
    const nsPrintfCString vprintfString(
        getStringViaVprintfCtor(format, "foo", "bar"));
    EXPECT_TRUE(printfString.Equals(vprintfString))
        << printfString.get() << " != " << vprintfString.get();
    EXPECT_TRUE(printfString.EqualsASCII(expectedOutput))
        << printfString.get() << " != " << expectedOutput;
  }

  {
    const int signedThree = 3;
    const unsigned int unsignedTen = 10;
    const char* format = "Integers %i %.3d %.2u %o %x %X";
    const char* expectedOutput = "Integers 3 003 10 12 a A";
    const nsPrintfCString printfString(format, signedThree, signedThree,
                                       unsignedTen, unsignedTen, unsignedTen,
                                       unsignedTen);
    const nsPrintfCString vprintfString(
        getStringViaVprintfCtor(format, signedThree, signedThree, unsignedTen,
                                unsignedTen, unsignedTen, unsignedTen));
    EXPECT_TRUE(printfString.Equals(vprintfString))
        << printfString.get() << " != " << vprintfString.get();
    EXPECT_TRUE(printfString.EqualsASCII(expectedOutput))
        << printfString.get() << " != " << expectedOutput;
  }

  {
    const char* format = "Floats %f %.0f %e %.2E";
    const char* expectedOutput = "Floats 1.500000 2 1.500000e+00 1.50E+00";
    const nsPrintfCString printfString(format, 1.5, 1.5, 1.5, 1.5);
    const nsPrintfCString vprintfString(
        getStringViaVprintfCtor(format, 1.5, 1.5, 1.5, 1.5));
    EXPECT_TRUE(printfString.Equals(vprintfString))
        << printfString.get() << " != " << vprintfString.get();
    EXPECT_TRUE(printfString.EqualsASCII(expectedOutput))
        << printfString.get() << " != " << expectedOutput;
  }
}

// Note the five calls in the loop, so divide by 100k
MOZ_GTEST_BENCH_F(Strings, PerfStripWhitespace, [this] {
  nsCString test1(mExample1Utf8);