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