convert_test.cc
Go to the documentation of this file.
00001 #include <errno.h>
00002 #include <stdarg.h>
00003 #include <stdio.h>
00004 #include <cctype>
00005 #include <cmath>
00006 #include <string>
00007 
00008 #include "gtest/gtest.h"
00009 #include "absl/strings/internal/str_format/bind.h"
00010 
00011 namespace absl {
00012 namespace str_format_internal {
00013 namespace {
00014 
00015 template <typename T, size_t N>
00016 size_t ArraySize(T (&)[N]) {
00017   return N;
00018 }
00019 
00020 std::string LengthModFor(float) { return ""; }
00021 std::string LengthModFor(double) { return ""; }
00022 std::string LengthModFor(long double) { return "L"; }
00023 std::string LengthModFor(char) { return "hh"; }
00024 std::string LengthModFor(signed char) { return "hh"; }
00025 std::string LengthModFor(unsigned char) { return "hh"; }
00026 std::string LengthModFor(short) { return "h"; }           // NOLINT
00027 std::string LengthModFor(unsigned short) { return "h"; }  // NOLINT
00028 std::string LengthModFor(int) { return ""; }
00029 std::string LengthModFor(unsigned) { return ""; }
00030 std::string LengthModFor(long) { return "l"; }                 // NOLINT
00031 std::string LengthModFor(unsigned long) { return "l"; }        // NOLINT
00032 std::string LengthModFor(long long) { return "ll"; }           // NOLINT
00033 std::string LengthModFor(unsigned long long) { return "ll"; }  // NOLINT
00034 
00035 std::string EscCharImpl(int v) {
00036   if (std::isprint(static_cast<unsigned char>(v))) {
00037     return std::string(1, static_cast<char>(v));
00038   }
00039   char buf[64];
00040   int n = snprintf(buf, sizeof(buf), "\\%#.2x",
00041                    static_cast<unsigned>(v & 0xff));
00042   assert(n > 0 && n < sizeof(buf));
00043   return std::string(buf, n);
00044 }
00045 
00046 std::string Esc(char v) { return EscCharImpl(v); }
00047 std::string Esc(signed char v) { return EscCharImpl(v); }
00048 std::string Esc(unsigned char v) { return EscCharImpl(v); }
00049 
00050 template <typename T>
00051 std::string Esc(const T &v) {
00052   std::ostringstream oss;
00053   oss << v;
00054   return oss.str();
00055 }
00056 
00057 void StrAppend(std::string *dst, const char *format, va_list ap) {
00058   // First try with a small fixed size buffer
00059   static const int kSpaceLength = 1024;
00060   char space[kSpaceLength];
00061 
00062   // It's possible for methods that use a va_list to invalidate
00063   // the data in it upon use.  The fix is to make a copy
00064   // of the structure before using it and use that copy instead.
00065   va_list backup_ap;
00066   va_copy(backup_ap, ap);
00067   int result = vsnprintf(space, kSpaceLength, format, backup_ap);
00068   va_end(backup_ap);
00069   if (result < kSpaceLength) {
00070     if (result >= 0) {
00071       // Normal case -- everything fit.
00072       dst->append(space, result);
00073       return;
00074     }
00075     if (result < 0) {
00076       // Just an error.
00077       return;
00078     }
00079   }
00080 
00081   // Increase the buffer size to the size requested by vsnprintf,
00082   // plus one for the closing \0.
00083   int length = result + 1;
00084   char *buf = new char[length];
00085 
00086   // Restore the va_list before we use it again
00087   va_copy(backup_ap, ap);
00088   result = vsnprintf(buf, length, format, backup_ap);
00089   va_end(backup_ap);
00090 
00091   if (result >= 0 && result < length) {
00092     // It fit
00093     dst->append(buf, result);
00094   }
00095   delete[] buf;
00096 }
00097 
00098 std::string StrPrint(const char *format, ...) {
00099   va_list ap;
00100   va_start(ap, format);
00101   std::string result;
00102   StrAppend(&result, format, ap);
00103   va_end(ap);
00104   return result;
00105 }
00106 
00107 class FormatConvertTest : public ::testing::Test { };
00108 
00109 template <typename T>
00110 void TestStringConvert(const T& str) {
00111   const FormatArgImpl args[] = {FormatArgImpl(str)};
00112   struct Expectation {
00113     const char *out;
00114     const char *fmt;
00115   };
00116   const Expectation kExpect[] = {
00117     {"hello",  "%1$s"      },
00118     {"",       "%1$.s"     },
00119     {"",       "%1$.0s"    },
00120     {"h",      "%1$.1s"    },
00121     {"he",     "%1$.2s"    },
00122     {"hello",  "%1$.10s"   },
00123     {" hello", "%1$6s"     },
00124     {"   he",  "%1$5.2s"   },
00125     {"he   ",  "%1$-5.2s"  },
00126     {"hello ", "%1$-6.10s" },
00127   };
00128   for (const Expectation &e : kExpect) {
00129     UntypedFormatSpecImpl format(e.fmt);
00130     EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
00131   }
00132 }
00133 
00134 TEST_F(FormatConvertTest, BasicString) {
00135   TestStringConvert("hello");  // As char array.
00136   TestStringConvert(static_cast<const char*>("hello"));
00137   TestStringConvert(std::string("hello"));
00138   TestStringConvert(string_view("hello"));
00139 }
00140 
00141 TEST_F(FormatConvertTest, NullString) {
00142   const char* p = nullptr;
00143   UntypedFormatSpecImpl format("%s");
00144   EXPECT_EQ("", FormatPack(format, {FormatArgImpl(p)}));
00145 }
00146 
00147 TEST_F(FormatConvertTest, StringPrecision) {
00148   // We cap at the precision.
00149   char c = 'a';
00150   const char* p = &c;
00151   UntypedFormatSpecImpl format("%.1s");
00152   EXPECT_EQ("a", FormatPack(format, {FormatArgImpl(p)}));
00153 
00154   // We cap at the nul terminator.
00155   p = "ABC";
00156   UntypedFormatSpecImpl format2("%.10s");
00157   EXPECT_EQ("ABC", FormatPack(format2, {FormatArgImpl(p)}));
00158 }
00159 
00160 TEST_F(FormatConvertTest, Pointer) {
00161 #ifdef _MSC_VER
00162   // MSVC's printf implementation prints pointers differently. We can't easily
00163   // compare our implementation to theirs.
00164   return;
00165 #endif
00166   static int x = 0;
00167   const int *xp = &x;
00168   char c = 'h';
00169   char *mcp = &c;
00170   const char *cp = "hi";
00171   const char *cnil = nullptr;
00172   const int *inil = nullptr;
00173   using VoidF = void (*)();
00174   VoidF fp = [] {}, fnil = nullptr;
00175   volatile char vc;
00176   volatile char* vcp = &vc;
00177   volatile char* vcnil = nullptr;
00178   const FormatArgImpl args[] = {
00179       FormatArgImpl(xp),   FormatArgImpl(cp),  FormatArgImpl(inil),
00180       FormatArgImpl(cnil), FormatArgImpl(mcp), FormatArgImpl(fp),
00181       FormatArgImpl(fnil), FormatArgImpl(vcp), FormatArgImpl(vcnil),
00182   };
00183   struct Expectation {
00184     std::string out;
00185     const char *fmt;
00186   };
00187   const Expectation kExpect[] = {
00188       {StrPrint("%p", &x), "%p"},
00189       {StrPrint("%20p", &x), "%20p"},
00190       {StrPrint("%.1p", &x), "%.1p"},
00191       {StrPrint("%.20p", &x), "%.20p"},
00192       {StrPrint("%30.20p", &x), "%30.20p"},
00193 
00194       {StrPrint("%-p", &x), "%-p"},
00195       {StrPrint("%-20p", &x), "%-20p"},
00196       {StrPrint("%-.1p", &x), "%-.1p"},
00197       {StrPrint("%.20p", &x), "%.20p"},
00198       {StrPrint("%-30.20p", &x), "%-30.20p"},
00199 
00200       {StrPrint("%p", cp), "%2$p"},   // const char*
00201       {"(nil)", "%3$p"},              // null const char *
00202       {"(nil)", "%4$p"},              // null const int *
00203       {StrPrint("%p", mcp), "%5$p"},  // nonconst char*
00204 
00205       {StrPrint("%p", fp), "%6$p"},   // function pointer
00206       {StrPrint("%p", vcp), "%8$p"},  // function pointer
00207 
00208 #ifndef __APPLE__
00209       // Apple's printf differs here (0x0 vs. nil)
00210       {StrPrint("%p", fnil), "%7$p"},   // null function pointer
00211       {StrPrint("%p", vcnil), "%9$p"},  // null function pointer
00212 #endif
00213   };
00214   for (const Expectation &e : kExpect) {
00215     UntypedFormatSpecImpl format(e.fmt);
00216     EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args))) << e.fmt;
00217   }
00218 }
00219 
00220 struct Cardinal {
00221   enum Pos { k1 = 1, k2 = 2, k3 = 3 };
00222   enum Neg { kM1 = -1, kM2 = -2, kM3 = -3 };
00223 };
00224 
00225 TEST_F(FormatConvertTest, Enum) {
00226   const Cardinal::Pos k3 = Cardinal::k3;
00227   const Cardinal::Neg km3 = Cardinal::kM3;
00228   const FormatArgImpl args[] = {FormatArgImpl(k3), FormatArgImpl(km3)};
00229   UntypedFormatSpecImpl format("%1$d");
00230   UntypedFormatSpecImpl format2("%2$d");
00231   EXPECT_EQ("3", FormatPack(format, absl::MakeSpan(args)));
00232   EXPECT_EQ("-3", FormatPack(format2, absl::MakeSpan(args)));
00233 }
00234 
00235 template <typename T>
00236 class TypedFormatConvertTest : public FormatConvertTest { };
00237 
00238 TYPED_TEST_SUITE_P(TypedFormatConvertTest);
00239 
00240 std::vector<std::string> AllFlagCombinations() {
00241   const char kFlags[] = {'-', '#', '0', '+', ' '};
00242   std::vector<std::string> result;
00243   for (size_t fsi = 0; fsi < (1ull << ArraySize(kFlags)); ++fsi) {
00244     std::string flag_set;
00245     for (size_t fi = 0; fi < ArraySize(kFlags); ++fi)
00246       if (fsi & (1ull << fi))
00247         flag_set += kFlags[fi];
00248     result.push_back(flag_set);
00249   }
00250   return result;
00251 }
00252 
00253 TYPED_TEST_P(TypedFormatConvertTest, AllIntsWithFlags) {
00254   typedef TypeParam T;
00255   typedef typename std::make_unsigned<T>::type UnsignedT;
00256   using remove_volatile_t = typename std::remove_volatile<T>::type;
00257   const T kMin = std::numeric_limits<remove_volatile_t>::min();
00258   const T kMax = std::numeric_limits<remove_volatile_t>::max();
00259   const T kVals[] = {
00260       remove_volatile_t(1),
00261       remove_volatile_t(2),
00262       remove_volatile_t(3),
00263       remove_volatile_t(123),
00264       remove_volatile_t(-1),
00265       remove_volatile_t(-2),
00266       remove_volatile_t(-3),
00267       remove_volatile_t(-123),
00268       remove_volatile_t(0),
00269       kMax - remove_volatile_t(1),
00270       kMax,
00271       kMin + remove_volatile_t(1),
00272       kMin,
00273   };
00274   const char kConvChars[] = {'d', 'i', 'u', 'o', 'x', 'X'};
00275   const std::string kWid[] = {"", "4", "10"};
00276   const std::string kPrec[] = {"", ".", ".0", ".4", ".10"};
00277 
00278   const std::vector<std::string> flag_sets = AllFlagCombinations();
00279 
00280   for (size_t vi = 0; vi < ArraySize(kVals); ++vi) {
00281     const T val = kVals[vi];
00282     SCOPED_TRACE(Esc(val));
00283     const FormatArgImpl args[] = {FormatArgImpl(val)};
00284     for (size_t ci = 0; ci < ArraySize(kConvChars); ++ci) {
00285       const char conv_char = kConvChars[ci];
00286       for (size_t fsi = 0; fsi < flag_sets.size(); ++fsi) {
00287         const std::string &flag_set = flag_sets[fsi];
00288         for (size_t wi = 0; wi < ArraySize(kWid); ++wi) {
00289           const std::string &wid = kWid[wi];
00290           for (size_t pi = 0; pi < ArraySize(kPrec); ++pi) {
00291             const std::string &prec = kPrec[pi];
00292 
00293             const bool is_signed_conv = (conv_char == 'd' || conv_char == 'i');
00294             const bool is_unsigned_to_signed =
00295                 !std::is_signed<T>::value && is_signed_conv;
00296             // Don't consider sign-related flags '+' and ' ' when doing
00297             // unsigned to signed conversions.
00298             if (is_unsigned_to_signed &&
00299                 flag_set.find_first_of("+ ") != std::string::npos) {
00300               continue;
00301             }
00302 
00303             std::string new_fmt("%");
00304             new_fmt += flag_set;
00305             new_fmt += wid;
00306             new_fmt += prec;
00307             // old and new always agree up to here.
00308             std::string old_fmt = new_fmt;
00309             new_fmt += conv_char;
00310             std::string old_result;
00311             if (is_unsigned_to_signed) {
00312               // don't expect agreement on unsigned formatted as signed,
00313               // as printf can't do that conversion properly. For those
00314               // cases, we do expect agreement with printf with a "%u"
00315               // and the unsigned equivalent of 'val'.
00316               UnsignedT uval = val;
00317               old_fmt += LengthModFor(uval);
00318               old_fmt += "u";
00319               old_result = StrPrint(old_fmt.c_str(), uval);
00320             } else {
00321               old_fmt += LengthModFor(val);
00322               old_fmt += conv_char;
00323               old_result = StrPrint(old_fmt.c_str(), val);
00324             }
00325 
00326             SCOPED_TRACE(std::string() + " old_fmt: \"" + old_fmt +
00327                          "\"'"
00328                          " new_fmt: \"" +
00329                          new_fmt + "\"");
00330             UntypedFormatSpecImpl format(new_fmt);
00331             EXPECT_EQ(old_result, FormatPack(format, absl::MakeSpan(args)));
00332           }
00333         }
00334       }
00335     }
00336   }
00337 }
00338 
00339 TYPED_TEST_P(TypedFormatConvertTest, Char) {
00340   typedef TypeParam T;
00341   using remove_volatile_t = typename std::remove_volatile<T>::type;
00342   static const T kMin = std::numeric_limits<remove_volatile_t>::min();
00343   static const T kMax = std::numeric_limits<remove_volatile_t>::max();
00344   T kVals[] = {
00345     remove_volatile_t(1), remove_volatile_t(2), remove_volatile_t(10),
00346     remove_volatile_t(-1), remove_volatile_t(-2), remove_volatile_t(-10),
00347     remove_volatile_t(0),
00348     kMin + remove_volatile_t(1), kMin,
00349     kMax - remove_volatile_t(1), kMax
00350   };
00351   for (const T &c : kVals) {
00352     const FormatArgImpl args[] = {FormatArgImpl(c)};
00353     UntypedFormatSpecImpl format("%c");
00354     EXPECT_EQ(StrPrint("%c", c), FormatPack(format, absl::MakeSpan(args)));
00355   }
00356 }
00357 
00358 REGISTER_TYPED_TEST_CASE_P(TypedFormatConvertTest, AllIntsWithFlags, Char);
00359 
00360 typedef ::testing::Types<
00361     int, unsigned, volatile int,
00362     short, unsigned short,
00363     long, unsigned long,
00364     long long, unsigned long long,
00365     signed char, unsigned char, char>
00366     AllIntTypes;
00367 INSTANTIATE_TYPED_TEST_CASE_P(TypedFormatConvertTestWithAllIntTypes,
00368                               TypedFormatConvertTest, AllIntTypes);
00369 
00370 TEST_F(FormatConvertTest, VectorBool) {
00371   // Make sure vector<bool>'s values behave as bools.
00372   std::vector<bool> v = {true, false};
00373   const std::vector<bool> cv = {true, false};
00374   EXPECT_EQ("1,0,1,0",
00375             FormatPack(UntypedFormatSpecImpl("%d,%d,%d,%d"),
00376                        absl::Span<const FormatArgImpl>(
00377                            {FormatArgImpl(v[0]), FormatArgImpl(v[1]),
00378                             FormatArgImpl(cv[0]), FormatArgImpl(cv[1])})));
00379 }
00380 
00381 TEST_F(FormatConvertTest, Uint128) {
00382   absl::uint128 v = static_cast<absl::uint128>(0x1234567890abcdef) * 1979;
00383   absl::uint128 max = absl::Uint128Max();
00384   const FormatArgImpl args[] = {FormatArgImpl(v), FormatArgImpl(max)};
00385 
00386   struct Case {
00387     const char* format;
00388     const char* expected;
00389   } cases[] = {
00390       {"%1$d", "2595989796776606496405"},
00391       {"%1$30d", "        2595989796776606496405"},
00392       {"%1$-30d", "2595989796776606496405        "},
00393       {"%1$u", "2595989796776606496405"},
00394       {"%1$x", "8cba9876066020f695"},
00395       {"%2$d", "340282366920938463463374607431768211455"},
00396       {"%2$u", "340282366920938463463374607431768211455"},
00397       {"%2$x", "ffffffffffffffffffffffffffffffff"},
00398   };
00399 
00400   for (auto c : cases) {
00401     UntypedFormatSpecImpl format(c.format);
00402     EXPECT_EQ(c.expected, FormatPack(format, absl::MakeSpan(args)));
00403   }
00404 }
00405 
00406 TEST_F(FormatConvertTest, Float) {
00407 #ifdef _MSC_VER
00408   // MSVC has a different rounding policy than us so we can't test our
00409   // implementation against the native one there.
00410   return;
00411 #endif  // _MSC_VER
00412 
00413   const char *const kFormats[] = {
00414       "%",  "%.3",  "%8.5",   "%9",   "%.60", "%.30",   "%03",    "%+",
00415       "% ", "%-10", "%#15.3", "%#.0", "%.0",  "%1$*2$", "%1$.*2$"};
00416 
00417   std::vector<double> doubles = {0.0,
00418                                  -0.0,
00419                                  .99999999999999,
00420                                  99999999999999.,
00421                                  std::numeric_limits<double>::max(),
00422                                  -std::numeric_limits<double>::max(),
00423                                  std::numeric_limits<double>::min(),
00424                                  -std::numeric_limits<double>::min(),
00425                                  std::numeric_limits<double>::lowest(),
00426                                  -std::numeric_limits<double>::lowest(),
00427                                  std::numeric_limits<double>::epsilon(),
00428                                  std::numeric_limits<double>::epsilon() + 1,
00429                                  std::numeric_limits<double>::infinity(),
00430                                  -std::numeric_limits<double>::infinity()};
00431 
00432 #ifndef __APPLE__
00433   // Apple formats NaN differently (+nan) vs. (nan)
00434   doubles.push_back(std::nan(""));
00435 #endif
00436 
00437   // Some regression tests.
00438   doubles.push_back(0.99999999999999989);
00439 
00440   if (std::numeric_limits<double>::has_denorm != std::denorm_absent) {
00441     doubles.push_back(std::numeric_limits<double>::denorm_min());
00442     doubles.push_back(-std::numeric_limits<double>::denorm_min());
00443   }
00444 
00445   for (double base :
00446        {1., 12., 123., 1234., 12345., 123456., 1234567., 12345678., 123456789.,
00447         1234567890., 12345678901., 123456789012., 1234567890123.}) {
00448     for (int exp = -123; exp <= 123; ++exp) {
00449       for (int sign : {1, -1}) {
00450         doubles.push_back(sign * std::ldexp(base, exp));
00451       }
00452     }
00453   }
00454 
00455   for (const char *fmt : kFormats) {
00456     for (char f : {'f', 'F',  //
00457                    'g', 'G',  //
00458                    'a', 'A',  //
00459                    'e', 'E'}) {
00460       std::string fmt_str = std::string(fmt) + f;
00461       for (double d : doubles) {
00462         int i = -10;
00463         FormatArgImpl args[2] = {FormatArgImpl(d), FormatArgImpl(i)};
00464         UntypedFormatSpecImpl format(fmt_str);
00465         // We use ASSERT_EQ here because failures are usually correlated and a
00466         // bug would print way too many failed expectations causing the test to
00467         // time out.
00468         ASSERT_EQ(StrPrint(fmt_str.c_str(), d, i),
00469                   FormatPack(format, absl::MakeSpan(args)))
00470             << fmt_str << " " << StrPrint("%.18g", d) << " "
00471             << StrPrint("%.999f", d);
00472       }
00473     }
00474   }
00475 }
00476 
00477 TEST_F(FormatConvertTest, LongDouble) {
00478   const char *const kFormats[] = {"%",    "%.3", "%8.5", "%9",
00479                                   "%.60", "%+",  "% ",   "%-10"};
00480 
00481   // This value is not representable in double, but it is in long double that
00482   // uses the extended format.
00483   // This is to verify that we are not truncating the value mistakenly through a
00484   // double.
00485   long double very_precise = 10000000000000000.25L;
00486 
00487   std::vector<long double> doubles = {
00488       0.0,
00489       -0.0,
00490       very_precise,
00491       1 / very_precise,
00492       std::numeric_limits<long double>::max(),
00493       -std::numeric_limits<long double>::max(),
00494       std::numeric_limits<long double>::min(),
00495       -std::numeric_limits<long double>::min(),
00496       std::numeric_limits<long double>::infinity(),
00497       -std::numeric_limits<long double>::infinity()};
00498 
00499   for (const char *fmt : kFormats) {
00500     for (char f : {'f', 'F',  //
00501                    'g', 'G',  //
00502                    'a', 'A',  //
00503                    'e', 'E'}) {
00504       std::string fmt_str = std::string(fmt) + 'L' + f;
00505       for (auto d : doubles) {
00506         FormatArgImpl arg(d);
00507         UntypedFormatSpecImpl format(fmt_str);
00508         // We use ASSERT_EQ here because failures are usually correlated and a
00509         // bug would print way too many failed expectations causing the test to
00510         // time out.
00511         ASSERT_EQ(StrPrint(fmt_str.c_str(), d),
00512                   FormatPack(format, {&arg, 1}))
00513             << fmt_str << " " << StrPrint("%.18Lg", d) << " "
00514             << StrPrint("%.999Lf", d);
00515       }
00516     }
00517   }
00518 }
00519 
00520 TEST_F(FormatConvertTest, IntAsFloat) {
00521   const int kMin = std::numeric_limits<int>::min();
00522   const int kMax = std::numeric_limits<int>::max();
00523   const int ia[] = {
00524     1, 2, 3, 123,
00525     -1, -2, -3, -123,
00526     0, kMax - 1, kMax, kMin + 1, kMin };
00527   for (const int fx : ia) {
00528     SCOPED_TRACE(fx);
00529     const FormatArgImpl args[] = {FormatArgImpl(fx)};
00530     struct Expectation {
00531       int line;
00532       std::string out;
00533       const char *fmt;
00534     };
00535     const double dx = static_cast<double>(fx);
00536     const Expectation kExpect[] = {
00537       { __LINE__, StrPrint("%f", dx), "%f" },
00538       { __LINE__, StrPrint("%12f", dx), "%12f" },
00539       { __LINE__, StrPrint("%.12f", dx), "%.12f" },
00540       { __LINE__, StrPrint("%12a", dx), "%12a" },
00541       { __LINE__, StrPrint("%.12a", dx), "%.12a" },
00542     };
00543     for (const Expectation &e : kExpect) {
00544       SCOPED_TRACE(e.line);
00545       SCOPED_TRACE(e.fmt);
00546       UntypedFormatSpecImpl format(e.fmt);
00547       EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
00548     }
00549   }
00550 }
00551 
00552 template <typename T>
00553 bool FormatFails(const char* test_format, T value) {
00554   std::string format_string = std::string("<<") + test_format + ">>";
00555   UntypedFormatSpecImpl format(format_string);
00556 
00557   int one = 1;
00558   const FormatArgImpl args[] = {FormatArgImpl(value), FormatArgImpl(one)};
00559   EXPECT_EQ(FormatPack(format, absl::MakeSpan(args)), "")
00560       << "format=" << test_format << " value=" << value;
00561   return FormatPack(format, absl::MakeSpan(args)).empty();
00562 }
00563 
00564 TEST_F(FormatConvertTest, ExpectedFailures) {
00565   // Int input
00566   EXPECT_TRUE(FormatFails("%p", 1));
00567   EXPECT_TRUE(FormatFails("%s", 1));
00568   EXPECT_TRUE(FormatFails("%n", 1));
00569 
00570   // Double input
00571   EXPECT_TRUE(FormatFails("%p", 1.));
00572   EXPECT_TRUE(FormatFails("%s", 1.));
00573   EXPECT_TRUE(FormatFails("%n", 1.));
00574   EXPECT_TRUE(FormatFails("%c", 1.));
00575   EXPECT_TRUE(FormatFails("%d", 1.));
00576   EXPECT_TRUE(FormatFails("%x", 1.));
00577   EXPECT_TRUE(FormatFails("%*d", 1.));
00578 
00579   // String input
00580   EXPECT_TRUE(FormatFails("%n", ""));
00581   EXPECT_TRUE(FormatFails("%c", ""));
00582   EXPECT_TRUE(FormatFails("%d", ""));
00583   EXPECT_TRUE(FormatFails("%x", ""));
00584   EXPECT_TRUE(FormatFails("%f", ""));
00585   EXPECT_TRUE(FormatFails("%*d", ""));
00586 }
00587 
00588 }  // namespace
00589 }  // namespace str_format_internal
00590 }  // namespace absl


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14