• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <errno.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 
5 #include <cctype>
6 #include <cmath>
7 #include <limits>
8 #include <string>
9 #include <thread>  // NOLINT
10 
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 #include "absl/base/internal/raw_logging.h"
14 #include "absl/strings/internal/str_format/bind.h"
15 #include "absl/strings/match.h"
16 #include "absl/types/optional.h"
17 
18 namespace absl {
19 ABSL_NAMESPACE_BEGIN
20 namespace str_format_internal {
21 namespace {
22 
23 struct NativePrintfTraits {
24   bool hex_float_has_glibc_rounding;
25   bool hex_float_prefers_denormal_repr;
26   bool hex_float_uses_minimal_precision_when_not_specified;
27   bool hex_float_optimizes_leading_digit_bit_count;
28 };
29 
30 template <typename T, size_t N>
ArraySize(T (&)[N])31 size_t ArraySize(T (&)[N]) {
32   return N;
33 }
34 
LengthModFor(float)35 std::string LengthModFor(float) { return ""; }
LengthModFor(double)36 std::string LengthModFor(double) { return ""; }
LengthModFor(long double)37 std::string LengthModFor(long double) { return "L"; }
LengthModFor(char)38 std::string LengthModFor(char) { return "hh"; }
LengthModFor(signed char)39 std::string LengthModFor(signed char) { return "hh"; }
LengthModFor(unsigned char)40 std::string LengthModFor(unsigned char) { return "hh"; }
LengthModFor(short)41 std::string LengthModFor(short) { return "h"; }           // NOLINT
LengthModFor(unsigned short)42 std::string LengthModFor(unsigned short) { return "h"; }  // NOLINT
LengthModFor(int)43 std::string LengthModFor(int) { return ""; }
LengthModFor(unsigned)44 std::string LengthModFor(unsigned) { return ""; }
LengthModFor(long)45 std::string LengthModFor(long) { return "l"; }                 // NOLINT
LengthModFor(unsigned long)46 std::string LengthModFor(unsigned long) { return "l"; }        // NOLINT
LengthModFor(long long)47 std::string LengthModFor(long long) { return "ll"; }           // NOLINT
LengthModFor(unsigned long long)48 std::string LengthModFor(unsigned long long) { return "ll"; }  // NOLINT
49 
EscCharImpl(int v)50 std::string EscCharImpl(int v) {
51   if (std::isprint(static_cast<unsigned char>(v))) {
52     return std::string(1, static_cast<char>(v));
53   }
54   char buf[64];
55   int n = snprintf(buf, sizeof(buf), "\\%#.2x",
56                    static_cast<unsigned>(v & 0xff));
57   assert(n > 0 && n < sizeof(buf));
58   return std::string(buf, n);
59 }
60 
Esc(char v)61 std::string Esc(char v) { return EscCharImpl(v); }
Esc(signed char v)62 std::string Esc(signed char v) { return EscCharImpl(v); }
Esc(unsigned char v)63 std::string Esc(unsigned char v) { return EscCharImpl(v); }
64 
65 template <typename T>
Esc(const T & v)66 std::string Esc(const T &v) {
67   std::ostringstream oss;
68   oss << v;
69   return oss.str();
70 }
71 
StrAppendV(std::string * dst,const char * format,va_list ap)72 void StrAppendV(std::string *dst, const char *format, va_list ap) {
73   // First try with a small fixed size buffer
74   static const int kSpaceLength = 1024;
75   char space[kSpaceLength];
76 
77   // It's possible for methods that use a va_list to invalidate
78   // the data in it upon use.  The fix is to make a copy
79   // of the structure before using it and use that copy instead.
80   va_list backup_ap;
81   va_copy(backup_ap, ap);
82   int result = vsnprintf(space, kSpaceLength, format, backup_ap);
83   va_end(backup_ap);
84   if (result < kSpaceLength) {
85     if (result >= 0) {
86       // Normal case -- everything fit.
87       dst->append(space, result);
88       return;
89     }
90     if (result < 0) {
91       // Just an error.
92       return;
93     }
94   }
95 
96   // Increase the buffer size to the size requested by vsnprintf,
97   // plus one for the closing \0.
98   int length = result + 1;
99   char *buf = new char[length];
100 
101   // Restore the va_list before we use it again
102   va_copy(backup_ap, ap);
103   result = vsnprintf(buf, length, format, backup_ap);
104   va_end(backup_ap);
105 
106   if (result >= 0 && result < length) {
107     // It fit
108     dst->append(buf, result);
109   }
110   delete[] buf;
111 }
112 
StrAppend(std::string * out,const char * format,...)113 void StrAppend(std::string *out, const char *format, ...) {
114   va_list ap;
115   va_start(ap, format);
116   StrAppendV(out, format, ap);
117   va_end(ap);
118 }
119 
StrPrint(const char * format,...)120 std::string StrPrint(const char *format, ...) {
121   va_list ap;
122   va_start(ap, format);
123   std::string result;
124   StrAppendV(&result, format, ap);
125   va_end(ap);
126   return result;
127 }
128 
VerifyNativeImplementationImpl()129 NativePrintfTraits VerifyNativeImplementationImpl() {
130   NativePrintfTraits result;
131 
132   // >>> hex_float_has_glibc_rounding. To have glibc's rounding behavior we need
133   // to meet three requirements:
134   //
135   //   - The threshold for rounding up is 8 (for e.g. MSVC uses 9).
136   //   - If the digits lower than than the 8 are non-zero then we round up.
137   //   - If the digits lower than the 8 are all zero then we round toward even.
138   //
139   // The numbers below represent all the cases covering {below,at,above} the
140   // threshold (8) with both {zero,non-zero} lower bits and both {even,odd}
141   // preceding digits.
142   const double d0079 = 65657.0;  // 0x1.0079p+16
143   const double d0179 = 65913.0;  // 0x1.0179p+16
144   const double d0080 = 65664.0;  // 0x1.0080p+16
145   const double d0180 = 65920.0;  // 0x1.0180p+16
146   const double d0081 = 65665.0;  // 0x1.0081p+16
147   const double d0181 = 65921.0;  // 0x1.0181p+16
148   result.hex_float_has_glibc_rounding =
149       StartsWith(StrPrint("%.2a", d0079), "0x1.00") &&
150       StartsWith(StrPrint("%.2a", d0179), "0x1.01") &&
151       StartsWith(StrPrint("%.2a", d0080), "0x1.00") &&
152       StartsWith(StrPrint("%.2a", d0180), "0x1.02") &&
153       StartsWith(StrPrint("%.2a", d0081), "0x1.01") &&
154       StartsWith(StrPrint("%.2a", d0181), "0x1.02");
155 
156   // >>> hex_float_prefers_denormal_repr. Formatting `denormal` on glibc yields
157   // "0x0.0000000000001p-1022", whereas on std libs that don't use denormal
158   // representation it would either be 0x1p-1074 or 0x1.0000000000000-1074.
159   const double denormal = std::numeric_limits<double>::denorm_min();
160   result.hex_float_prefers_denormal_repr =
161       StartsWith(StrPrint("%a", denormal), "0x0.0000000000001");
162 
163   // >>> hex_float_uses_minimal_precision_when_not_specified. Some (non-glibc)
164   // libs will format the following as "0x1.0079000000000p+16".
165   result.hex_float_uses_minimal_precision_when_not_specified =
166       (StrPrint("%a", d0079) == "0x1.0079p+16");
167 
168   // >>> hex_float_optimizes_leading_digit_bit_count. The number 1.5, when
169   // formatted by glibc should yield "0x1.8p+0" for `double` and "0xcp-3" for
170   // `long double`, i.e., number of bits in the leading digit is adapted to the
171   // number of bits in the mantissa.
172   const double d_15 = 1.5;
173   const long double ld_15 = 1.5;
174   result.hex_float_optimizes_leading_digit_bit_count =
175       StartsWith(StrPrint("%a", d_15), "0x1.8") &&
176       StartsWith(StrPrint("%La", ld_15), "0xc");
177 
178   return result;
179 }
180 
VerifyNativeImplementation()181 const NativePrintfTraits &VerifyNativeImplementation() {
182   static NativePrintfTraits native_traits = VerifyNativeImplementationImpl();
183   return native_traits;
184 }
185 
186 class FormatConvertTest : public ::testing::Test { };
187 
188 template <typename T>
TestStringConvert(const T & str)189 void TestStringConvert(const T& str) {
190   const FormatArgImpl args[] = {FormatArgImpl(str)};
191   struct Expectation {
192     const char *out;
193     const char *fmt;
194   };
195   const Expectation kExpect[] = {
196     {"hello",  "%1$s"      },
197     {"",       "%1$.s"     },
198     {"",       "%1$.0s"    },
199     {"h",      "%1$.1s"    },
200     {"he",     "%1$.2s"    },
201     {"hello",  "%1$.10s"   },
202     {" hello", "%1$6s"     },
203     {"   he",  "%1$5.2s"   },
204     {"he   ",  "%1$-5.2s"  },
205     {"hello ", "%1$-6.10s" },
206   };
207   for (const Expectation &e : kExpect) {
208     UntypedFormatSpecImpl format(e.fmt);
209     EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
210   }
211 }
212 
TEST_F(FormatConvertTest,BasicString)213 TEST_F(FormatConvertTest, BasicString) {
214   TestStringConvert("hello");  // As char array.
215   TestStringConvert(static_cast<const char*>("hello"));
216   TestStringConvert(std::string("hello"));
217   TestStringConvert(string_view("hello"));
218 }
219 
TEST_F(FormatConvertTest,NullString)220 TEST_F(FormatConvertTest, NullString) {
221   const char* p = nullptr;
222   UntypedFormatSpecImpl format("%s");
223   EXPECT_EQ("", FormatPack(format, {FormatArgImpl(p)}));
224 }
225 
TEST_F(FormatConvertTest,StringPrecision)226 TEST_F(FormatConvertTest, StringPrecision) {
227   // We cap at the precision.
228   char c = 'a';
229   const char* p = &c;
230   UntypedFormatSpecImpl format("%.1s");
231   EXPECT_EQ("a", FormatPack(format, {FormatArgImpl(p)}));
232 
233   // We cap at the NUL-terminator.
234   p = "ABC";
235   UntypedFormatSpecImpl format2("%.10s");
236   EXPECT_EQ("ABC", FormatPack(format2, {FormatArgImpl(p)}));
237 }
238 
239 // Pointer formatting is implementation defined. This checks that the argument
240 // can be matched to `ptr`.
241 MATCHER_P(MatchesPointerString, ptr, "") {
242   if (ptr == nullptr && arg == "(nil)") {
243     return true;
244   }
245   void* parsed = nullptr;
246   if (sscanf(arg.c_str(), "%p", &parsed) != 1) {
247     ABSL_RAW_LOG(FATAL, "Could not parse %s", arg.c_str());
248   }
249   return ptr == parsed;
250 }
251 
TEST_F(FormatConvertTest,Pointer)252 TEST_F(FormatConvertTest, Pointer) {
253   static int x = 0;
254   const int *xp = &x;
255   char c = 'h';
256   char *mcp = &c;
257   const char *cp = "hi";
258   const char *cnil = nullptr;
259   const int *inil = nullptr;
260   using VoidF = void (*)();
261   VoidF fp = [] {}, fnil = nullptr;
262   volatile char vc;
263   volatile char *vcp = &vc;
264   volatile char *vcnil = nullptr;
265   const FormatArgImpl args_array[] = {
266       FormatArgImpl(xp),   FormatArgImpl(cp),  FormatArgImpl(inil),
267       FormatArgImpl(cnil), FormatArgImpl(mcp), FormatArgImpl(fp),
268       FormatArgImpl(fnil), FormatArgImpl(vcp), FormatArgImpl(vcnil),
269   };
270   auto args = absl::MakeConstSpan(args_array);
271 
272   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%p"), args),
273               MatchesPointerString(&x));
274   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%20p"), args),
275               MatchesPointerString(&x));
276   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%.1p"), args),
277               MatchesPointerString(&x));
278   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%.20p"), args),
279               MatchesPointerString(&x));
280   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%30.20p"), args),
281               MatchesPointerString(&x));
282 
283   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%-p"), args),
284               MatchesPointerString(&x));
285   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%-20p"), args),
286               MatchesPointerString(&x));
287   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%-.1p"), args),
288               MatchesPointerString(&x));
289   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%.20p"), args),
290               MatchesPointerString(&x));
291   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%-30.20p"), args),
292               MatchesPointerString(&x));
293 
294   // const char*
295   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%2$p"), args),
296               MatchesPointerString(cp));
297   // null const int*
298   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%3$p"), args),
299               MatchesPointerString(nullptr));
300   // null const char*
301   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%4$p"), args),
302               MatchesPointerString(nullptr));
303   // nonconst char*
304   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%5$p"), args),
305               MatchesPointerString(mcp));
306 
307   // function pointers
308   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%6$p"), args),
309               MatchesPointerString(reinterpret_cast<const void*>(fp)));
310   EXPECT_THAT(
311       FormatPack(UntypedFormatSpecImpl("%8$p"), args),
312       MatchesPointerString(reinterpret_cast<volatile const void *>(vcp)));
313 
314   // null function pointers
315   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%7$p"), args),
316               MatchesPointerString(nullptr));
317   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%9$p"), args),
318               MatchesPointerString(nullptr));
319 }
320 
321 struct Cardinal {
322   enum Pos { k1 = 1, k2 = 2, k3 = 3 };
323   enum Neg { kM1 = -1, kM2 = -2, kM3 = -3 };
324 };
325 
TEST_F(FormatConvertTest,Enum)326 TEST_F(FormatConvertTest, Enum) {
327   const Cardinal::Pos k3 = Cardinal::k3;
328   const Cardinal::Neg km3 = Cardinal::kM3;
329   const FormatArgImpl args[] = {FormatArgImpl(k3), FormatArgImpl(km3)};
330   UntypedFormatSpecImpl format("%1$d");
331   UntypedFormatSpecImpl format2("%2$d");
332   EXPECT_EQ("3", FormatPack(format, absl::MakeSpan(args)));
333   EXPECT_EQ("-3", FormatPack(format2, absl::MakeSpan(args)));
334 }
335 
336 template <typename T>
337 class TypedFormatConvertTest : public FormatConvertTest { };
338 
339 TYPED_TEST_SUITE_P(TypedFormatConvertTest);
340 
AllFlagCombinations()341 std::vector<std::string> AllFlagCombinations() {
342   const char kFlags[] = {'-', '#', '0', '+', ' '};
343   std::vector<std::string> result;
344   for (size_t fsi = 0; fsi < (1ull << ArraySize(kFlags)); ++fsi) {
345     std::string flag_set;
346     for (size_t fi = 0; fi < ArraySize(kFlags); ++fi)
347       if (fsi & (1ull << fi))
348         flag_set += kFlags[fi];
349     result.push_back(flag_set);
350   }
351   return result;
352 }
353 
TYPED_TEST_P(TypedFormatConvertTest,AllIntsWithFlags)354 TYPED_TEST_P(TypedFormatConvertTest, AllIntsWithFlags) {
355   typedef TypeParam T;
356   typedef typename std::make_unsigned<T>::type UnsignedT;
357   using remove_volatile_t = typename std::remove_volatile<T>::type;
358   const T kMin = std::numeric_limits<remove_volatile_t>::min();
359   const T kMax = std::numeric_limits<remove_volatile_t>::max();
360   const T kVals[] = {
361       remove_volatile_t(1),
362       remove_volatile_t(2),
363       remove_volatile_t(3),
364       remove_volatile_t(123),
365       remove_volatile_t(-1),
366       remove_volatile_t(-2),
367       remove_volatile_t(-3),
368       remove_volatile_t(-123),
369       remove_volatile_t(0),
370       kMax - remove_volatile_t(1),
371       kMax,
372       kMin + remove_volatile_t(1),
373       kMin,
374   };
375   const char kConvChars[] = {'d', 'i', 'u', 'o', 'x', 'X'};
376   const std::string kWid[] = {"", "4", "10"};
377   const std::string kPrec[] = {"", ".", ".0", ".4", ".10"};
378 
379   const std::vector<std::string> flag_sets = AllFlagCombinations();
380 
381   for (size_t vi = 0; vi < ArraySize(kVals); ++vi) {
382     const T val = kVals[vi];
383     SCOPED_TRACE(Esc(val));
384     const FormatArgImpl args[] = {FormatArgImpl(val)};
385     for (size_t ci = 0; ci < ArraySize(kConvChars); ++ci) {
386       const char conv_char = kConvChars[ci];
387       for (size_t fsi = 0; fsi < flag_sets.size(); ++fsi) {
388         const std::string &flag_set = flag_sets[fsi];
389         for (size_t wi = 0; wi < ArraySize(kWid); ++wi) {
390           const std::string &wid = kWid[wi];
391           for (size_t pi = 0; pi < ArraySize(kPrec); ++pi) {
392             const std::string &prec = kPrec[pi];
393 
394             const bool is_signed_conv = (conv_char == 'd' || conv_char == 'i');
395             const bool is_unsigned_to_signed =
396                 !std::is_signed<T>::value && is_signed_conv;
397             // Don't consider sign-related flags '+' and ' ' when doing
398             // unsigned to signed conversions.
399             if (is_unsigned_to_signed &&
400                 flag_set.find_first_of("+ ") != std::string::npos) {
401               continue;
402             }
403 
404             std::string new_fmt("%");
405             new_fmt += flag_set;
406             new_fmt += wid;
407             new_fmt += prec;
408             // old and new always agree up to here.
409             std::string old_fmt = new_fmt;
410             new_fmt += conv_char;
411             std::string old_result;
412             if (is_unsigned_to_signed) {
413               // don't expect agreement on unsigned formatted as signed,
414               // as printf can't do that conversion properly. For those
415               // cases, we do expect agreement with printf with a "%u"
416               // and the unsigned equivalent of 'val'.
417               UnsignedT uval = val;
418               old_fmt += LengthModFor(uval);
419               old_fmt += "u";
420               old_result = StrPrint(old_fmt.c_str(), uval);
421             } else {
422               old_fmt += LengthModFor(val);
423               old_fmt += conv_char;
424               old_result = StrPrint(old_fmt.c_str(), val);
425             }
426 
427             SCOPED_TRACE(std::string() + " old_fmt: \"" + old_fmt +
428                          "\"'"
429                          " new_fmt: \"" +
430                          new_fmt + "\"");
431             UntypedFormatSpecImpl format(new_fmt);
432             EXPECT_EQ(old_result, FormatPack(format, absl::MakeSpan(args)));
433           }
434         }
435       }
436     }
437   }
438 }
439 
TYPED_TEST_P(TypedFormatConvertTest,Char)440 TYPED_TEST_P(TypedFormatConvertTest, Char) {
441   typedef TypeParam T;
442   using remove_volatile_t = typename std::remove_volatile<T>::type;
443   static const T kMin = std::numeric_limits<remove_volatile_t>::min();
444   static const T kMax = std::numeric_limits<remove_volatile_t>::max();
445   T kVals[] = {
446     remove_volatile_t(1), remove_volatile_t(2), remove_volatile_t(10),
447     remove_volatile_t(-1), remove_volatile_t(-2), remove_volatile_t(-10),
448     remove_volatile_t(0),
449     kMin + remove_volatile_t(1), kMin,
450     kMax - remove_volatile_t(1), kMax
451   };
452   for (const T &c : kVals) {
453     const FormatArgImpl args[] = {FormatArgImpl(c)};
454     UntypedFormatSpecImpl format("%c");
455     EXPECT_EQ(StrPrint("%c", c), FormatPack(format, absl::MakeSpan(args)));
456   }
457 }
458 
459 REGISTER_TYPED_TEST_CASE_P(TypedFormatConvertTest, AllIntsWithFlags, Char);
460 
461 typedef ::testing::Types<
462     int, unsigned, volatile int,
463     short, unsigned short,
464     long, unsigned long,
465     long long, unsigned long long,
466     signed char, unsigned char, char>
467     AllIntTypes;
468 INSTANTIATE_TYPED_TEST_CASE_P(TypedFormatConvertTestWithAllIntTypes,
469                               TypedFormatConvertTest, AllIntTypes);
TEST_F(FormatConvertTest,VectorBool)470 TEST_F(FormatConvertTest, VectorBool) {
471   // Make sure vector<bool>'s values behave as bools.
472   std::vector<bool> v = {true, false};
473   const std::vector<bool> cv = {true, false};
474   EXPECT_EQ("1,0,1,0",
475             FormatPack(UntypedFormatSpecImpl("%d,%d,%d,%d"),
476                        absl::Span<const FormatArgImpl>(
477                            {FormatArgImpl(v[0]), FormatArgImpl(v[1]),
478                             FormatArgImpl(cv[0]), FormatArgImpl(cv[1])})));
479 }
480 
481 
TEST_F(FormatConvertTest,Int128)482 TEST_F(FormatConvertTest, Int128) {
483   absl::int128 positive = static_cast<absl::int128>(0x1234567890abcdef) * 1979;
484   absl::int128 negative = -positive;
485   absl::int128 max = absl::Int128Max(), min = absl::Int128Min();
486   const FormatArgImpl args[] = {FormatArgImpl(positive),
487                                 FormatArgImpl(negative), FormatArgImpl(max),
488                                 FormatArgImpl(min)};
489 
490   struct Case {
491     const char* format;
492     const char* expected;
493   } cases[] = {
494       {"%1$d", "2595989796776606496405"},
495       {"%1$30d", "        2595989796776606496405"},
496       {"%1$-30d", "2595989796776606496405        "},
497       {"%1$u", "2595989796776606496405"},
498       {"%1$x", "8cba9876066020f695"},
499       {"%2$d", "-2595989796776606496405"},
500       {"%2$30d", "       -2595989796776606496405"},
501       {"%2$-30d", "-2595989796776606496405       "},
502       {"%2$u", "340282366920938460867384810655161715051"},
503       {"%2$x", "ffffffffffffff73456789f99fdf096b"},
504       {"%3$d", "170141183460469231731687303715884105727"},
505       {"%3$u", "170141183460469231731687303715884105727"},
506       {"%3$x", "7fffffffffffffffffffffffffffffff"},
507       {"%4$d", "-170141183460469231731687303715884105728"},
508       {"%4$x", "80000000000000000000000000000000"},
509   };
510 
511   for (auto c : cases) {
512     UntypedFormatSpecImpl format(c.format);
513     EXPECT_EQ(c.expected, FormatPack(format, absl::MakeSpan(args)));
514   }
515 }
516 
TEST_F(FormatConvertTest,Uint128)517 TEST_F(FormatConvertTest, Uint128) {
518   absl::uint128 v = static_cast<absl::uint128>(0x1234567890abcdef) * 1979;
519   absl::uint128 max = absl::Uint128Max();
520   const FormatArgImpl args[] = {FormatArgImpl(v), FormatArgImpl(max)};
521 
522   struct Case {
523     const char* format;
524     const char* expected;
525   } cases[] = {
526       {"%1$d", "2595989796776606496405"},
527       {"%1$30d", "        2595989796776606496405"},
528       {"%1$-30d", "2595989796776606496405        "},
529       {"%1$u", "2595989796776606496405"},
530       {"%1$x", "8cba9876066020f695"},
531       {"%2$d", "340282366920938463463374607431768211455"},
532       {"%2$u", "340282366920938463463374607431768211455"},
533       {"%2$x", "ffffffffffffffffffffffffffffffff"},
534   };
535 
536   for (auto c : cases) {
537     UntypedFormatSpecImpl format(c.format);
538     EXPECT_EQ(c.expected, FormatPack(format, absl::MakeSpan(args)));
539   }
540 }
541 
542 template <typename Floating>
TestWithMultipleFormatsHelper(const std::vector<Floating> & floats)543 void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) {
544   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
545   // Reserve the space to ensure we don't allocate memory in the output itself.
546   std::string str_format_result;
547   str_format_result.reserve(1 << 20);
548   std::string string_printf_result;
549   string_printf_result.reserve(1 << 20);
550 
551   const char *const kFormats[] = {
552       "%",  "%.3", "%8.5", "%500",   "%.5000", "%.60", "%.30",   "%03",
553       "%+", "% ",  "%-10", "%#15.3", "%#.0",   "%.0",  "%1$*2$", "%1$.*2$"};
554 
555   for (const char *fmt : kFormats) {
556     for (char f : {'f', 'F',  //
557                    'g', 'G',  //
558                    'a', 'A',  //
559                    'e', 'E'}) {
560       std::string fmt_str = std::string(fmt) + f;
561 
562       if (fmt == absl::string_view("%.5000") && f != 'f' && f != 'F' &&
563           f != 'a' && f != 'A') {
564         // This particular test takes way too long with snprintf.
565         // Disable for the case we are not implementing natively.
566         continue;
567       }
568 
569       if ((f == 'a' || f == 'A') &&
570           !native_traits.hex_float_has_glibc_rounding) {
571         continue;
572       }
573 
574       for (Floating d : floats) {
575         if (!native_traits.hex_float_prefers_denormal_repr &&
576             (f == 'a' || f == 'A') && std::fpclassify(d) == FP_SUBNORMAL) {
577           continue;
578         }
579         int i = -10;
580         FormatArgImpl args[2] = {FormatArgImpl(d), FormatArgImpl(i)};
581         UntypedFormatSpecImpl format(fmt_str);
582 
583         string_printf_result.clear();
584         StrAppend(&string_printf_result, fmt_str.c_str(), d, i);
585         str_format_result.clear();
586 
587         {
588           AppendPack(&str_format_result, format, absl::MakeSpan(args));
589         }
590 
591         if (string_printf_result != str_format_result) {
592           // We use ASSERT_EQ here because failures are usually correlated and a
593           // bug would print way too many failed expectations causing the test
594           // to time out.
595           ASSERT_EQ(string_printf_result, str_format_result)
596               << fmt_str << " " << StrPrint("%.18g", d) << " "
597               << StrPrint("%a", d) << " " << StrPrint("%.50f", d);
598         }
599       }
600     }
601   }
602 }
603 
TEST_F(FormatConvertTest,Float)604 TEST_F(FormatConvertTest, Float) {
605 #ifdef _MSC_VER
606   // MSVC has a different rounding policy than us so we can't test our
607   // implementation against the native one there.
608   return;
609 #endif  // _MSC_VER
610 
611   std::vector<float> floats = {0.0f,
612                                -0.0f,
613                                .9999999f,
614                                9999999.f,
615                                std::numeric_limits<float>::max(),
616                                -std::numeric_limits<float>::max(),
617                                std::numeric_limits<float>::min(),
618                                -std::numeric_limits<float>::min(),
619                                std::numeric_limits<float>::lowest(),
620                                -std::numeric_limits<float>::lowest(),
621                                std::numeric_limits<float>::epsilon(),
622                                std::numeric_limits<float>::epsilon() + 1.0f,
623                                std::numeric_limits<float>::infinity(),
624                                -std::numeric_limits<float>::infinity()};
625 
626   // Some regression tests.
627   floats.push_back(0.999999989f);
628 
629   if (std::numeric_limits<float>::has_denorm != std::denorm_absent) {
630     floats.push_back(std::numeric_limits<float>::denorm_min());
631     floats.push_back(-std::numeric_limits<float>::denorm_min());
632   }
633 
634   for (float base :
635        {1.f, 12.f, 123.f, 1234.f, 12345.f, 123456.f, 1234567.f, 12345678.f,
636         123456789.f, 1234567890.f, 12345678901.f, 12345678.f, 12345678.f}) {
637     for (int exp = -123; exp <= 123; ++exp) {
638       for (int sign : {1, -1}) {
639         floats.push_back(sign * std::ldexp(base, exp));
640       }
641     }
642   }
643 
644   for (int exp = -300; exp <= 300; ++exp) {
645     const float all_ones_mantissa = 0xffffff;
646     floats.push_back(std::ldexp(all_ones_mantissa, exp));
647   }
648 
649   // Remove duplicates to speed up the logic below.
650   std::sort(floats.begin(), floats.end());
651   floats.erase(std::unique(floats.begin(), floats.end()), floats.end());
652 
653 #ifndef __APPLE__
654   // Apple formats NaN differently (+nan) vs. (nan)
655   floats.push_back(std::nan(""));
656 #endif
657 
658   TestWithMultipleFormatsHelper(floats);
659 }
660 
TEST_F(FormatConvertTest,Double)661 TEST_F(FormatConvertTest, Double) {
662 #ifdef _MSC_VER
663   // MSVC has a different rounding policy than us so we can't test our
664   // implementation against the native one there.
665   return;
666 #endif  // _MSC_VER
667 
668   std::vector<double> doubles = {0.0,
669                                  -0.0,
670                                  .99999999999999,
671                                  99999999999999.,
672                                  std::numeric_limits<double>::max(),
673                                  -std::numeric_limits<double>::max(),
674                                  std::numeric_limits<double>::min(),
675                                  -std::numeric_limits<double>::min(),
676                                  std::numeric_limits<double>::lowest(),
677                                  -std::numeric_limits<double>::lowest(),
678                                  std::numeric_limits<double>::epsilon(),
679                                  std::numeric_limits<double>::epsilon() + 1,
680                                  std::numeric_limits<double>::infinity(),
681                                  -std::numeric_limits<double>::infinity()};
682 
683   // Some regression tests.
684   doubles.push_back(0.99999999999999989);
685 
686   if (std::numeric_limits<double>::has_denorm != std::denorm_absent) {
687     doubles.push_back(std::numeric_limits<double>::denorm_min());
688     doubles.push_back(-std::numeric_limits<double>::denorm_min());
689   }
690 
691   for (double base :
692        {1., 12., 123., 1234., 12345., 123456., 1234567., 12345678., 123456789.,
693         1234567890., 12345678901., 123456789012., 1234567890123.}) {
694     for (int exp = -123; exp <= 123; ++exp) {
695       for (int sign : {1, -1}) {
696         doubles.push_back(sign * std::ldexp(base, exp));
697       }
698     }
699   }
700 
701   // Workaround libc bug.
702   // https://sourceware.org/bugzilla/show_bug.cgi?id=22142
703   const bool gcc_bug_22142 =
704       StrPrint("%f", std::numeric_limits<double>::max()) !=
705       "1797693134862315708145274237317043567980705675258449965989174768031"
706       "5726078002853876058955863276687817154045895351438246423432132688946"
707       "4182768467546703537516986049910576551282076245490090389328944075868"
708       "5084551339423045832369032229481658085593321233482747978262041447231"
709       "68738177180919299881250404026184124858368.000000";
710 
711   if (!gcc_bug_22142) {
712     for (int exp = -300; exp <= 300; ++exp) {
713       const double all_ones_mantissa = 0x1fffffffffffff;
714       doubles.push_back(std::ldexp(all_ones_mantissa, exp));
715     }
716   }
717 
718   if (gcc_bug_22142) {
719     for (auto &d : doubles) {
720       using L = std::numeric_limits<double>;
721       double d2 = std::abs(d);
722       if (d2 == L::max() || d2 == L::min() || d2 == L::denorm_min()) {
723         d = 0;
724       }
725     }
726   }
727 
728   // Remove duplicates to speed up the logic below.
729   std::sort(doubles.begin(), doubles.end());
730   doubles.erase(std::unique(doubles.begin(), doubles.end()), doubles.end());
731 
732 #ifndef __APPLE__
733   // Apple formats NaN differently (+nan) vs. (nan)
734   doubles.push_back(std::nan(""));
735 #endif
736 
737   TestWithMultipleFormatsHelper(doubles);
738 }
739 
TEST_F(FormatConvertTest,DoubleRound)740 TEST_F(FormatConvertTest, DoubleRound) {
741   std::string s;
742   const auto format = [&](const char *fmt, double d) -> std::string & {
743     s.clear();
744     FormatArgImpl args[1] = {FormatArgImpl(d)};
745     AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
746 #if !defined(_MSC_VER)
747     // MSVC has a different rounding policy than us so we can't test our
748     // implementation against the native one there.
749     EXPECT_EQ(StrPrint(fmt, d), s);
750 #endif  // _MSC_VER
751 
752     return s;
753   };
754   // All of these values have to be exactly represented.
755   // Otherwise we might not be testing what we think we are testing.
756 
757   // These values can fit in a 64bit "fast" representation.
758   const double exact_value = 0.00000000000005684341886080801486968994140625;
759   assert(exact_value == std::pow(2, -44));
760   // Round up at a 5xx.
761   EXPECT_EQ(format("%.13f", exact_value), "0.0000000000001");
762   // Round up at a >5
763   EXPECT_EQ(format("%.14f", exact_value), "0.00000000000006");
764   // Round down at a <5
765   EXPECT_EQ(format("%.16f", exact_value), "0.0000000000000568");
766   // Nine handling
767   EXPECT_EQ(format("%.35f", exact_value),
768             "0.00000000000005684341886080801486969");
769   EXPECT_EQ(format("%.36f", exact_value),
770             "0.000000000000056843418860808014869690");
771   // Round down the last nine.
772   EXPECT_EQ(format("%.37f", exact_value),
773             "0.0000000000000568434188608080148696899");
774   EXPECT_EQ(format("%.10f", 0.000003814697265625), "0.0000038147");
775   // Round up the last nine
776   EXPECT_EQ(format("%.11f", 0.000003814697265625), "0.00000381470");
777   EXPECT_EQ(format("%.12f", 0.000003814697265625), "0.000003814697");
778 
779   // Round to even (down)
780   EXPECT_EQ(format("%.43f", exact_value),
781             "0.0000000000000568434188608080148696899414062");
782   // Exact
783   EXPECT_EQ(format("%.44f", exact_value),
784             "0.00000000000005684341886080801486968994140625");
785   // Round to even (up), let make the last digits 75 instead of 25
786   EXPECT_EQ(format("%.43f", exact_value + std::pow(2, -43)),
787             "0.0000000000001705302565824240446090698242188");
788   // Exact, just to check.
789   EXPECT_EQ(format("%.44f", exact_value + std::pow(2, -43)),
790             "0.00000000000017053025658242404460906982421875");
791 
792   // This value has to be small enough that it won't fit in the uint128
793   // representation for printing.
794   const double small_exact_value =
795       0.000000000000000000000000000000000000752316384526264005099991383822237233803945956334136013765601092018187046051025390625;  // NOLINT
796   assert(small_exact_value == std::pow(2, -120));
797   // Round up at a 5xx.
798   EXPECT_EQ(format("%.37f", small_exact_value),
799             "0.0000000000000000000000000000000000008");
800   // Round down at a <5
801   EXPECT_EQ(format("%.38f", small_exact_value),
802             "0.00000000000000000000000000000000000075");
803   // Round up at a >5
804   EXPECT_EQ(format("%.41f", small_exact_value),
805             "0.00000000000000000000000000000000000075232");
806   // Nine handling
807   EXPECT_EQ(format("%.55f", small_exact_value),
808             "0.0000000000000000000000000000000000007523163845262640051");
809   EXPECT_EQ(format("%.56f", small_exact_value),
810             "0.00000000000000000000000000000000000075231638452626400510");
811   EXPECT_EQ(format("%.57f", small_exact_value),
812             "0.000000000000000000000000000000000000752316384526264005100");
813   EXPECT_EQ(format("%.58f", small_exact_value),
814             "0.0000000000000000000000000000000000007523163845262640051000");
815   // Round down the last nine
816   EXPECT_EQ(format("%.59f", small_exact_value),
817             "0.00000000000000000000000000000000000075231638452626400509999");
818   // Round up the last nine
819   EXPECT_EQ(format("%.79f", small_exact_value),
820             "0.000000000000000000000000000000000000"
821             "7523163845262640050999913838222372338039460");
822 
823   // Round to even (down)
824   EXPECT_EQ(format("%.119f", small_exact_value),
825             "0.000000000000000000000000000000000000"
826             "75231638452626400509999138382223723380"
827             "394595633413601376560109201818704605102539062");
828   // Exact
829   EXPECT_EQ(format("%.120f", small_exact_value),
830             "0.000000000000000000000000000000000000"
831             "75231638452626400509999138382223723380"
832             "3945956334136013765601092018187046051025390625");
833   // Round to even (up), let make the last digits 75 instead of 25
834   EXPECT_EQ(format("%.119f", small_exact_value + std::pow(2, -119)),
835             "0.000000000000000000000000000000000002"
836             "25694915357879201529997415146671170141"
837             "183786900240804129680327605456113815307617188");
838   // Exact, just to check.
839   EXPECT_EQ(format("%.120f", small_exact_value + std::pow(2, -119)),
840             "0.000000000000000000000000000000000002"
841             "25694915357879201529997415146671170141"
842             "1837869002408041296803276054561138153076171875");
843 }
844 
TEST_F(FormatConvertTest,DoubleRoundA)845 TEST_F(FormatConvertTest, DoubleRoundA) {
846   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
847   std::string s;
848   const auto format = [&](const char *fmt, double d) -> std::string & {
849     s.clear();
850     FormatArgImpl args[1] = {FormatArgImpl(d)};
851     AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
852     if (native_traits.hex_float_has_glibc_rounding) {
853       EXPECT_EQ(StrPrint(fmt, d), s);
854     }
855     return s;
856   };
857 
858   // 0x1.00018000p+100
859   const double on_boundary_odd = 1267679614447900152596896153600.0;
860   EXPECT_EQ(format("%.0a", on_boundary_odd), "0x1p+100");
861   EXPECT_EQ(format("%.1a", on_boundary_odd), "0x1.0p+100");
862   EXPECT_EQ(format("%.2a", on_boundary_odd), "0x1.00p+100");
863   EXPECT_EQ(format("%.3a", on_boundary_odd), "0x1.000p+100");
864   EXPECT_EQ(format("%.4a", on_boundary_odd), "0x1.0002p+100");  // round
865   EXPECT_EQ(format("%.5a", on_boundary_odd), "0x1.00018p+100");
866   EXPECT_EQ(format("%.6a", on_boundary_odd), "0x1.000180p+100");
867 
868   // 0x1.00028000p-2
869   const double on_boundary_even = 0.250009536743164062500;
870   EXPECT_EQ(format("%.0a", on_boundary_even), "0x1p-2");
871   EXPECT_EQ(format("%.1a", on_boundary_even), "0x1.0p-2");
872   EXPECT_EQ(format("%.2a", on_boundary_even), "0x1.00p-2");
873   EXPECT_EQ(format("%.3a", on_boundary_even), "0x1.000p-2");
874   EXPECT_EQ(format("%.4a", on_boundary_even), "0x1.0002p-2");  // no round
875   EXPECT_EQ(format("%.5a", on_boundary_even), "0x1.00028p-2");
876   EXPECT_EQ(format("%.6a", on_boundary_even), "0x1.000280p-2");
877 
878   // 0x1.00018001p+1
879   const double slightly_over = 2.00004577683284878730773925781250;
880   EXPECT_EQ(format("%.0a", slightly_over), "0x1p+1");
881   EXPECT_EQ(format("%.1a", slightly_over), "0x1.0p+1");
882   EXPECT_EQ(format("%.2a", slightly_over), "0x1.00p+1");
883   EXPECT_EQ(format("%.3a", slightly_over), "0x1.000p+1");
884   EXPECT_EQ(format("%.4a", slightly_over), "0x1.0002p+1");
885   EXPECT_EQ(format("%.5a", slightly_over), "0x1.00018p+1");
886   EXPECT_EQ(format("%.6a", slightly_over), "0x1.000180p+1");
887 
888   // 0x1.00017fffp+0
889   const double slightly_under = 1.000022887950763106346130371093750;
890   EXPECT_EQ(format("%.0a", slightly_under), "0x1p+0");
891   EXPECT_EQ(format("%.1a", slightly_under), "0x1.0p+0");
892   EXPECT_EQ(format("%.2a", slightly_under), "0x1.00p+0");
893   EXPECT_EQ(format("%.3a", slightly_under), "0x1.000p+0");
894   EXPECT_EQ(format("%.4a", slightly_under), "0x1.0001p+0");
895   EXPECT_EQ(format("%.5a", slightly_under), "0x1.00018p+0");
896   EXPECT_EQ(format("%.6a", slightly_under), "0x1.000180p+0");
897   EXPECT_EQ(format("%.7a", slightly_under), "0x1.0001800p+0");
898 
899   // 0x1.1b3829ac28058p+3
900   const double hex_value = 8.85060580848964661981881363317370414733886718750;
901   EXPECT_EQ(format("%.0a", hex_value), "0x1p+3");
902   EXPECT_EQ(format("%.1a", hex_value), "0x1.2p+3");
903   EXPECT_EQ(format("%.2a", hex_value), "0x1.1bp+3");
904   EXPECT_EQ(format("%.3a", hex_value), "0x1.1b4p+3");
905   EXPECT_EQ(format("%.4a", hex_value), "0x1.1b38p+3");
906   EXPECT_EQ(format("%.5a", hex_value), "0x1.1b383p+3");
907   EXPECT_EQ(format("%.6a", hex_value), "0x1.1b382ap+3");
908   EXPECT_EQ(format("%.7a", hex_value), "0x1.1b3829bp+3");
909   EXPECT_EQ(format("%.8a", hex_value), "0x1.1b3829acp+3");
910   EXPECT_EQ(format("%.9a", hex_value), "0x1.1b3829ac3p+3");
911   EXPECT_EQ(format("%.10a", hex_value), "0x1.1b3829ac28p+3");
912   EXPECT_EQ(format("%.11a", hex_value), "0x1.1b3829ac280p+3");
913   EXPECT_EQ(format("%.12a", hex_value), "0x1.1b3829ac2806p+3");
914   EXPECT_EQ(format("%.13a", hex_value), "0x1.1b3829ac28058p+3");
915   EXPECT_EQ(format("%.14a", hex_value), "0x1.1b3829ac280580p+3");
916   EXPECT_EQ(format("%.15a", hex_value), "0x1.1b3829ac2805800p+3");
917   EXPECT_EQ(format("%.16a", hex_value), "0x1.1b3829ac28058000p+3");
918   EXPECT_EQ(format("%.17a", hex_value), "0x1.1b3829ac280580000p+3");
919   EXPECT_EQ(format("%.18a", hex_value), "0x1.1b3829ac2805800000p+3");
920   EXPECT_EQ(format("%.19a", hex_value), "0x1.1b3829ac28058000000p+3");
921   EXPECT_EQ(format("%.20a", hex_value), "0x1.1b3829ac280580000000p+3");
922   EXPECT_EQ(format("%.21a", hex_value), "0x1.1b3829ac2805800000000p+3");
923 
924   // 0x1.0818283848586p+3
925   const double hex_value2 = 8.2529488658208371987257123691961169242858886718750;
926   EXPECT_EQ(format("%.0a", hex_value2), "0x1p+3");
927   EXPECT_EQ(format("%.1a", hex_value2), "0x1.1p+3");
928   EXPECT_EQ(format("%.2a", hex_value2), "0x1.08p+3");
929   EXPECT_EQ(format("%.3a", hex_value2), "0x1.082p+3");
930   EXPECT_EQ(format("%.4a", hex_value2), "0x1.0818p+3");
931   EXPECT_EQ(format("%.5a", hex_value2), "0x1.08183p+3");
932   EXPECT_EQ(format("%.6a", hex_value2), "0x1.081828p+3");
933   EXPECT_EQ(format("%.7a", hex_value2), "0x1.0818284p+3");
934   EXPECT_EQ(format("%.8a", hex_value2), "0x1.08182838p+3");
935   EXPECT_EQ(format("%.9a", hex_value2), "0x1.081828385p+3");
936   EXPECT_EQ(format("%.10a", hex_value2), "0x1.0818283848p+3");
937   EXPECT_EQ(format("%.11a", hex_value2), "0x1.08182838486p+3");
938   EXPECT_EQ(format("%.12a", hex_value2), "0x1.081828384858p+3");
939   EXPECT_EQ(format("%.13a", hex_value2), "0x1.0818283848586p+3");
940   EXPECT_EQ(format("%.14a", hex_value2), "0x1.08182838485860p+3");
941   EXPECT_EQ(format("%.15a", hex_value2), "0x1.081828384858600p+3");
942   EXPECT_EQ(format("%.16a", hex_value2), "0x1.0818283848586000p+3");
943   EXPECT_EQ(format("%.17a", hex_value2), "0x1.08182838485860000p+3");
944   EXPECT_EQ(format("%.18a", hex_value2), "0x1.081828384858600000p+3");
945   EXPECT_EQ(format("%.19a", hex_value2), "0x1.0818283848586000000p+3");
946   EXPECT_EQ(format("%.20a", hex_value2), "0x1.08182838485860000000p+3");
947   EXPECT_EQ(format("%.21a", hex_value2), "0x1.081828384858600000000p+3");
948 }
949 
TEST_F(FormatConvertTest,LongDoubleRoundA)950 TEST_F(FormatConvertTest, LongDoubleRoundA) {
951   if (std::numeric_limits<long double>::digits % 4 != 0) {
952     // This test doesn't really make sense to run on platforms where a long
953     // double has a different mantissa size (mod 4) than Prod, since then the
954     // leading digit will be formatted differently.
955     return;
956   }
957   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
958   std::string s;
959   const auto format = [&](const char *fmt, long double d) -> std::string & {
960     s.clear();
961     FormatArgImpl args[1] = {FormatArgImpl(d)};
962     AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
963     if (native_traits.hex_float_has_glibc_rounding &&
964         native_traits.hex_float_optimizes_leading_digit_bit_count) {
965       EXPECT_EQ(StrPrint(fmt, d), s);
966     }
967     return s;
968   };
969 
970   // 0x8.8p+4
971   const long double on_boundary_even = 136.0;
972   EXPECT_EQ(format("%.0La", on_boundary_even), "0x8p+4");
973   EXPECT_EQ(format("%.1La", on_boundary_even), "0x8.8p+4");
974   EXPECT_EQ(format("%.2La", on_boundary_even), "0x8.80p+4");
975   EXPECT_EQ(format("%.3La", on_boundary_even), "0x8.800p+4");
976   EXPECT_EQ(format("%.4La", on_boundary_even), "0x8.8000p+4");
977   EXPECT_EQ(format("%.5La", on_boundary_even), "0x8.80000p+4");
978   EXPECT_EQ(format("%.6La", on_boundary_even), "0x8.800000p+4");
979 
980   // 0x9.8p+4
981   const long double on_boundary_odd = 152.0;
982   EXPECT_EQ(format("%.0La", on_boundary_odd), "0xap+4");
983   EXPECT_EQ(format("%.1La", on_boundary_odd), "0x9.8p+4");
984   EXPECT_EQ(format("%.2La", on_boundary_odd), "0x9.80p+4");
985   EXPECT_EQ(format("%.3La", on_boundary_odd), "0x9.800p+4");
986   EXPECT_EQ(format("%.4La", on_boundary_odd), "0x9.8000p+4");
987   EXPECT_EQ(format("%.5La", on_boundary_odd), "0x9.80000p+4");
988   EXPECT_EQ(format("%.6La", on_boundary_odd), "0x9.800000p+4");
989 
990   // 0x8.80001p+24
991   const long double slightly_over = 142606352.0;
992   EXPECT_EQ(format("%.0La", slightly_over), "0x9p+24");
993   EXPECT_EQ(format("%.1La", slightly_over), "0x8.8p+24");
994   EXPECT_EQ(format("%.2La", slightly_over), "0x8.80p+24");
995   EXPECT_EQ(format("%.3La", slightly_over), "0x8.800p+24");
996   EXPECT_EQ(format("%.4La", slightly_over), "0x8.8000p+24");
997   EXPECT_EQ(format("%.5La", slightly_over), "0x8.80001p+24");
998   EXPECT_EQ(format("%.6La", slightly_over), "0x8.800010p+24");
999 
1000   // 0x8.7ffffp+24
1001   const long double slightly_under = 142606320.0;
1002   EXPECT_EQ(format("%.0La", slightly_under), "0x8p+24");
1003   EXPECT_EQ(format("%.1La", slightly_under), "0x8.8p+24");
1004   EXPECT_EQ(format("%.2La", slightly_under), "0x8.80p+24");
1005   EXPECT_EQ(format("%.3La", slightly_under), "0x8.800p+24");
1006   EXPECT_EQ(format("%.4La", slightly_under), "0x8.8000p+24");
1007   EXPECT_EQ(format("%.5La", slightly_under), "0x8.7ffffp+24");
1008   EXPECT_EQ(format("%.6La", slightly_under), "0x8.7ffff0p+24");
1009   EXPECT_EQ(format("%.7La", slightly_under), "0x8.7ffff00p+24");
1010 
1011   // 0xc.0828384858688000p+128
1012   const long double eights = 4094231060438608800781871108094404067328.0;
1013   EXPECT_EQ(format("%.0La", eights), "0xcp+128");
1014   EXPECT_EQ(format("%.1La", eights), "0xc.1p+128");
1015   EXPECT_EQ(format("%.2La", eights), "0xc.08p+128");
1016   EXPECT_EQ(format("%.3La", eights), "0xc.083p+128");
1017   EXPECT_EQ(format("%.4La", eights), "0xc.0828p+128");
1018   EXPECT_EQ(format("%.5La", eights), "0xc.08284p+128");
1019   EXPECT_EQ(format("%.6La", eights), "0xc.082838p+128");
1020   EXPECT_EQ(format("%.7La", eights), "0xc.0828385p+128");
1021   EXPECT_EQ(format("%.8La", eights), "0xc.08283848p+128");
1022   EXPECT_EQ(format("%.9La", eights), "0xc.082838486p+128");
1023   EXPECT_EQ(format("%.10La", eights), "0xc.0828384858p+128");
1024   EXPECT_EQ(format("%.11La", eights), "0xc.08283848587p+128");
1025   EXPECT_EQ(format("%.12La", eights), "0xc.082838485868p+128");
1026   EXPECT_EQ(format("%.13La", eights), "0xc.0828384858688p+128");
1027   EXPECT_EQ(format("%.14La", eights), "0xc.08283848586880p+128");
1028   EXPECT_EQ(format("%.15La", eights), "0xc.082838485868800p+128");
1029   EXPECT_EQ(format("%.16La", eights), "0xc.0828384858688000p+128");
1030 }
1031 
1032 // We don't actually store the results. This is just to exercise the rest of the
1033 // machinery.
1034 struct NullSink {
AbslFormatFlush(NullSink * sink,string_view str)1035   friend void AbslFormatFlush(NullSink *sink, string_view str) {}
1036 };
1037 
1038 template <typename... T>
FormatWithNullSink(absl::string_view fmt,const T &...a)1039 bool FormatWithNullSink(absl::string_view fmt, const T &... a) {
1040   NullSink sink;
1041   FormatArgImpl args[] = {FormatArgImpl(a)...};
1042   return FormatUntyped(&sink, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
1043 }
1044 
TEST_F(FormatConvertTest,ExtremeWidthPrecision)1045 TEST_F(FormatConvertTest, ExtremeWidthPrecision) {
1046   for (const char *fmt : {"f"}) {
1047     for (double d : {1e-100, 1.0, 1e100}) {
1048       constexpr int max = std::numeric_limits<int>::max();
1049       EXPECT_TRUE(FormatWithNullSink(std::string("%.*") + fmt, max, d));
1050       EXPECT_TRUE(FormatWithNullSink(std::string("%1.*") + fmt, max, d));
1051       EXPECT_TRUE(FormatWithNullSink(std::string("%*") + fmt, max, d));
1052       EXPECT_TRUE(FormatWithNullSink(std::string("%*.*") + fmt, max, max, d));
1053     }
1054   }
1055 }
1056 
TEST_F(FormatConvertTest,LongDouble)1057 TEST_F(FormatConvertTest, LongDouble) {
1058 #ifdef _MSC_VER
1059   // MSVC has a different rounding policy than us so we can't test our
1060   // implementation against the native one there.
1061   return;
1062 #endif  // _MSC_VER
1063   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
1064   const char *const kFormats[] = {"%",    "%.3", "%8.5", "%9",  "%.5000",
1065                                   "%.60", "%+",  "% ",   "%-10"};
1066 
1067   std::vector<long double> doubles = {
1068       0.0,
1069       -0.0,
1070       std::numeric_limits<long double>::max(),
1071       -std::numeric_limits<long double>::max(),
1072       std::numeric_limits<long double>::min(),
1073       -std::numeric_limits<long double>::min(),
1074       std::numeric_limits<long double>::infinity(),
1075       -std::numeric_limits<long double>::infinity()};
1076 
1077   for (long double base : {1.L, 12.L, 123.L, 1234.L, 12345.L, 123456.L,
1078                            1234567.L, 12345678.L, 123456789.L, 1234567890.L,
1079                            12345678901.L, 123456789012.L, 1234567890123.L,
1080                            // This value is not representable in double, but it
1081                            // is in long double that uses the extended format.
1082                            // This is to verify that we are not truncating the
1083                            // value mistakenly through a double.
1084                            10000000000000000.25L}) {
1085     for (int exp : {-1000, -500, 0, 500, 1000}) {
1086       for (int sign : {1, -1}) {
1087         doubles.push_back(sign * std::ldexp(base, exp));
1088         doubles.push_back(sign / std::ldexp(base, exp));
1089       }
1090     }
1091   }
1092 
1093   // Regression tests
1094   //
1095   // Using a string literal because not all platforms support hex literals or it
1096   // might be out of range.
1097   doubles.push_back(std::strtold("-0xf.ffffffb5feafffbp-16324L", nullptr));
1098 
1099   for (const char *fmt : kFormats) {
1100     for (char f : {'f', 'F',  //
1101                    'g', 'G',  //
1102                    'a', 'A',  //
1103                    'e', 'E'}) {
1104       std::string fmt_str = std::string(fmt) + 'L' + f;
1105 
1106       if (fmt == absl::string_view("%.5000") && f != 'f' && f != 'F' &&
1107           f != 'a' && f != 'A') {
1108         // This particular test takes way too long with snprintf.
1109         // Disable for the case we are not implementing natively.
1110         continue;
1111       }
1112 
1113       if (f == 'a' || f == 'A') {
1114         if (!native_traits.hex_float_has_glibc_rounding ||
1115             !native_traits.hex_float_optimizes_leading_digit_bit_count) {
1116           continue;
1117         }
1118       }
1119 
1120       for (auto d : doubles) {
1121         FormatArgImpl arg(d);
1122         UntypedFormatSpecImpl format(fmt_str);
1123         // We use ASSERT_EQ here because failures are usually correlated and a
1124         // bug would print way too many failed expectations causing the test to
1125         // time out.
1126         ASSERT_EQ(StrPrint(fmt_str.c_str(), d), FormatPack(format, {&arg, 1}))
1127             << fmt_str << " " << StrPrint("%.18Lg", d) << " "
1128             << StrPrint("%La", d) << " " << StrPrint("%.1080Lf", d);
1129       }
1130     }
1131   }
1132 }
1133 
TEST_F(FormatConvertTest,IntAsDouble)1134 TEST_F(FormatConvertTest, IntAsDouble) {
1135   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
1136   const int kMin = std::numeric_limits<int>::min();
1137   const int kMax = std::numeric_limits<int>::max();
1138   const int ia[] = {
1139     1, 2, 3, 123,
1140     -1, -2, -3, -123,
1141     0, kMax - 1, kMax, kMin + 1, kMin };
1142   for (const int fx : ia) {
1143     SCOPED_TRACE(fx);
1144     const FormatArgImpl args[] = {FormatArgImpl(fx)};
1145     struct Expectation {
1146       int line;
1147       std::string out;
1148       const char *fmt;
1149     };
1150     const double dx = static_cast<double>(fx);
1151     std::vector<Expectation> expect = {
1152         {__LINE__, StrPrint("%f", dx), "%f"},
1153         {__LINE__, StrPrint("%12f", dx), "%12f"},
1154         {__LINE__, StrPrint("%.12f", dx), "%.12f"},
1155         {__LINE__, StrPrint("%.12a", dx), "%.12a"},
1156     };
1157     if (native_traits.hex_float_uses_minimal_precision_when_not_specified) {
1158       Expectation ex = {__LINE__, StrPrint("%12a", dx), "%12a"};
1159       expect.push_back(ex);
1160     }
1161     for (const Expectation &e : expect) {
1162       SCOPED_TRACE(e.line);
1163       SCOPED_TRACE(e.fmt);
1164       UntypedFormatSpecImpl format(e.fmt);
1165       EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
1166     }
1167   }
1168 }
1169 
1170 template <typename T>
FormatFails(const char * test_format,T value)1171 bool FormatFails(const char* test_format, T value) {
1172   std::string format_string = std::string("<<") + test_format + ">>";
1173   UntypedFormatSpecImpl format(format_string);
1174 
1175   int one = 1;
1176   const FormatArgImpl args[] = {FormatArgImpl(value), FormatArgImpl(one)};
1177   EXPECT_EQ(FormatPack(format, absl::MakeSpan(args)), "")
1178       << "format=" << test_format << " value=" << value;
1179   return FormatPack(format, absl::MakeSpan(args)).empty();
1180 }
1181 
TEST_F(FormatConvertTest,ExpectedFailures)1182 TEST_F(FormatConvertTest, ExpectedFailures) {
1183   // Int input
1184   EXPECT_TRUE(FormatFails("%p", 1));
1185   EXPECT_TRUE(FormatFails("%s", 1));
1186   EXPECT_TRUE(FormatFails("%n", 1));
1187 
1188   // Double input
1189   EXPECT_TRUE(FormatFails("%p", 1.));
1190   EXPECT_TRUE(FormatFails("%s", 1.));
1191   EXPECT_TRUE(FormatFails("%n", 1.));
1192   EXPECT_TRUE(FormatFails("%c", 1.));
1193   EXPECT_TRUE(FormatFails("%d", 1.));
1194   EXPECT_TRUE(FormatFails("%x", 1.));
1195   EXPECT_TRUE(FormatFails("%*d", 1.));
1196 
1197   // String input
1198   EXPECT_TRUE(FormatFails("%n", ""));
1199   EXPECT_TRUE(FormatFails("%c", ""));
1200   EXPECT_TRUE(FormatFails("%d", ""));
1201   EXPECT_TRUE(FormatFails("%x", ""));
1202   EXPECT_TRUE(FormatFails("%f", ""));
1203   EXPECT_TRUE(FormatFails("%*d", ""));
1204 }
1205 
1206 // Sanity check to make sure that we are testing what we think we're testing on
1207 // e.g. the x86_64+glibc platform.
TEST_F(FormatConvertTest,GlibcHasCorrectTraits)1208 TEST_F(FormatConvertTest, GlibcHasCorrectTraits) {
1209 #if !defined(__GLIBC__) || !defined(__x86_64__)
1210   return;
1211 #endif
1212   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
1213   // If one of the following tests break then it is either because the above PP
1214   // macro guards failed to exclude a new platform (likely) or because something
1215   // has changed in the implemention of glibc sprintf float formatting behavior.
1216   // If the latter, then the code that computes these flags needs to be
1217   // revisited and/or possibly the StrFormat implementation.
1218   EXPECT_TRUE(native_traits.hex_float_has_glibc_rounding);
1219   EXPECT_TRUE(native_traits.hex_float_prefers_denormal_repr);
1220   EXPECT_TRUE(
1221       native_traits.hex_float_uses_minimal_precision_when_not_specified);
1222   EXPECT_TRUE(native_traits.hex_float_optimizes_leading_digit_bit_count);
1223 }
1224 
1225 }  // namespace
1226 }  // namespace str_format_internal
1227 ABSL_NAMESPACE_END
1228 }  // namespace absl
1229