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