xref: /llvm-project/libc/test/src/stdlib/StrfromTest.h (revision e1d64b766274f707ef338bcd4e3bc6fb264fa06a)
183e96977SVinayak Dev //===-- A template class for testing strfrom functions ----------*- C++ -*-===//
283e96977SVinayak Dev //
383e96977SVinayak Dev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
483e96977SVinayak Dev // See https://llvm.org/LICENSE.txt for license information.
583e96977SVinayak Dev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
683e96977SVinayak Dev //
783e96977SVinayak Dev //===----------------------------------------------------------------------===//
883e96977SVinayak Dev 
983e96977SVinayak Dev #include "src/__support/CPP/type_traits.h"
106373577aSVinayak Dev #include "src/__support/FPUtil/FPBits.h"
1183e96977SVinayak Dev #include "test/UnitTest/Test.h"
1283e96977SVinayak Dev 
1383e96977SVinayak Dev #define ASSERT_STREQ_LEN(actual_written, actual_str, expected_str)             \
1483e96977SVinayak Dev   EXPECT_EQ(actual_written, static_cast<int>(sizeof(expected_str) - 1));       \
1583e96977SVinayak Dev   EXPECT_STREQ(actual_str, expected_str);
1683e96977SVinayak Dev 
1783e96977SVinayak Dev template <typename InputT>
1883e96977SVinayak Dev class StrfromTest : public LIBC_NAMESPACE::testing::Test {
1983e96977SVinayak Dev 
2083e96977SVinayak Dev   static const bool is_single_prec =
2183e96977SVinayak Dev       LIBC_NAMESPACE::cpp::is_same<InputT, float>::value;
2283e96977SVinayak Dev   static const bool is_double_prec =
2383e96977SVinayak Dev       LIBC_NAMESPACE::cpp::is_same<InputT, double>::value;
2483e96977SVinayak Dev 
2583e96977SVinayak Dev   using FunctionT = int (*)(char *, size_t, const char *, InputT fp);
2683e96977SVinayak Dev 
2783e96977SVinayak Dev public:
2883e96977SVinayak Dev   void floatDecimalFormat(FunctionT func) {
2983e96977SVinayak Dev     if (is_single_prec)
3083e96977SVinayak Dev       floatDecimalSinglePrec(func);
3183e96977SVinayak Dev     else if (is_double_prec)
3283e96977SVinayak Dev       floatDecimalDoublePrec(func);
3383e96977SVinayak Dev     else
3483e96977SVinayak Dev       floatDecimalLongDoublePrec(func);
3583e96977SVinayak Dev   }
3683e96977SVinayak Dev 
3783e96977SVinayak Dev   void floatHexExpFormat(FunctionT func) {
3883e96977SVinayak Dev     if (is_single_prec)
3983e96977SVinayak Dev       floatHexExpSinglePrec(func);
4083e96977SVinayak Dev     else if (is_double_prec)
4183e96977SVinayak Dev       floatHexExpDoublePrec(func);
4283e96977SVinayak Dev     else
4383e96977SVinayak Dev       floatHexExpLongDoublePrec(func);
4483e96977SVinayak Dev   }
4583e96977SVinayak Dev 
4683e96977SVinayak Dev   void floatDecimalExpFormat(FunctionT func) {
4783e96977SVinayak Dev     if (is_single_prec)
4883e96977SVinayak Dev       floatDecimalExpSinglePrec(func);
4983e96977SVinayak Dev     else if (is_double_prec)
5083e96977SVinayak Dev       floatDecimalExpDoublePrec(func);
5183e96977SVinayak Dev     else
5283e96977SVinayak Dev       floatDecimalExpLongDoublePrec(func);
5383e96977SVinayak Dev   }
5483e96977SVinayak Dev 
5583e96977SVinayak Dev   void floatDecimalAutoFormat(FunctionT func) {
5683e96977SVinayak Dev     if (is_single_prec)
5783e96977SVinayak Dev       floatDecimalAutoSinglePrec(func);
5883e96977SVinayak Dev     else if (is_double_prec)
5983e96977SVinayak Dev       floatDecimalAutoDoublePrec(func);
6083e96977SVinayak Dev     else
6183e96977SVinayak Dev       floatDecimalAutoLongDoublePrec(func);
6283e96977SVinayak Dev   }
6383e96977SVinayak Dev 
6483e96977SVinayak Dev   void improperFormatString(FunctionT func) {
6583e96977SVinayak Dev     char buff[100];
6683e96977SVinayak Dev     int written;
6783e96977SVinayak Dev     const bool is_long_double = !is_single_prec && !is_double_prec;
6883e96977SVinayak Dev 
6983e96977SVinayak Dev     written = func(buff, 37, "A simple string with no conversions.", 1.0);
7083e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "A simple string with no conversions.");
7183e96977SVinayak Dev 
7283e96977SVinayak Dev     written =
7383e96977SVinayak Dev         func(buff, 37,
7483e96977SVinayak Dev              "%A simple string with one conversion, should overwrite.", 1.0);
756373577aSVinayak Dev     if (is_long_double) {
766373577aSVinayak Dev #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
776373577aSVinayak Dev       ASSERT_STREQ_LEN(written, buff, "0X8P-3");
786373577aSVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
796373577aSVinayak Dev       ASSERT_STREQ_LEN(written, buff, "0X1P+0");
806373577aSVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
816373577aSVinayak Dev       ASSERT_STREQ_LEN(written, buff, "0X1P+0");
826373577aSVinayak Dev #endif
836373577aSVinayak Dev     } else {
846373577aSVinayak Dev       // not long double
856373577aSVinayak Dev       ASSERT_STREQ_LEN(written, buff, "0X1P+0");
866373577aSVinayak Dev     }
8783e96977SVinayak Dev     written = func(buff, 74,
8883e96977SVinayak Dev                    "A simple string with one conversion in %A "
8983e96977SVinayak Dev                    "between, writes string as it is",
9083e96977SVinayak Dev                    1.0);
9183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff,
9283e96977SVinayak Dev                      "A simple string with one conversion in %A between, "
9383e96977SVinayak Dev                      "writes string as it is");
9483e96977SVinayak Dev 
9583e96977SVinayak Dev     written = func(buff, 36, "A simple string with one conversion", 1.0);
9683e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "A simple string with one conversion");
9783e96977SVinayak Dev 
9883e96977SVinayak Dev     written = func(buff, 20, "%1f", 1234567890.0);
9983e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "%1f");
10083e96977SVinayak Dev   }
10183e96977SVinayak Dev 
10283e96977SVinayak Dev   void insufficentBufsize(FunctionT func) {
10383e96977SVinayak Dev     char buff[20];
10483e96977SVinayak Dev     int written;
10583e96977SVinayak Dev 
10683e96977SVinayak Dev     written = func(buff, 5, "%f", 1234567890.0);
10783e96977SVinayak Dev     EXPECT_EQ(written, 17);
10883e96977SVinayak Dev     ASSERT_STREQ(buff, "1234");
10983e96977SVinayak Dev 
11083e96977SVinayak Dev     written = func(buff, 5, "%.5f", 1.05);
11183e96977SVinayak Dev     EXPECT_EQ(written, 7);
11283e96977SVinayak Dev     ASSERT_STREQ(buff, "1.05");
11383e96977SVinayak Dev 
11483e96977SVinayak Dev     written = func(buff, 0, "%g", 1.0);
11583e96977SVinayak Dev     EXPECT_EQ(written, 1);
11683e96977SVinayak Dev     ASSERT_STREQ(buff, "1.05"); // Make sure that buff has not changed
11783e96977SVinayak Dev   }
11883e96977SVinayak Dev 
1196373577aSVinayak Dev   void infNanValues(FunctionT func) {
1206373577aSVinayak Dev     if (is_double_prec)
1216373577aSVinayak Dev       doublePrecInfNan(func);
1226373577aSVinayak Dev     else if (!is_single_prec)
1236373577aSVinayak Dev       longDoublePrecInfNan(func);
1246373577aSVinayak Dev   }
1256373577aSVinayak Dev 
12683e96977SVinayak Dev   void floatDecimalSinglePrec(FunctionT func) {
12783e96977SVinayak Dev     char buff[70];
12883e96977SVinayak Dev     int written;
12983e96977SVinayak Dev 
13083e96977SVinayak Dev     written = func(buff, 16, "%f", 1.0);
13183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.000000");
13283e96977SVinayak Dev 
13383e96977SVinayak Dev     written = func(buff, 20, "%f", 1234567890.0);
13483e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1234567936.000000");
13583e96977SVinayak Dev 
13683e96977SVinayak Dev     written = func(buff, 67, "%.3f", 1.0);
13783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.000");
13883e96977SVinayak Dev   }
13983e96977SVinayak Dev 
14083e96977SVinayak Dev   void floatDecimalDoublePrec(FunctionT func) {
14183e96977SVinayak Dev     char buff[500];
14283e96977SVinayak Dev     int written;
14383e96977SVinayak Dev 
14483e96977SVinayak Dev     written = func(buff, 99, "%f", 1.0);
14583e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.000000");
14683e96977SVinayak Dev 
14783e96977SVinayak Dev     written = func(buff, 99, "%F", -1.0);
14883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-1.000000");
14983e96977SVinayak Dev 
15083e96977SVinayak Dev     written = func(buff, 99, "%f", -1.234567);
15183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-1.234567");
15283e96977SVinayak Dev 
15383e96977SVinayak Dev     written = func(buff, 99, "%f", 0.0);
15483e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0.000000");
15583e96977SVinayak Dev 
15683e96977SVinayak Dev     written = func(buff, 99, "%f", 1.5);
15783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.500000");
15883e96977SVinayak Dev 
159*e1d64b76SMichael Jones // Dyadic float is only accurate to ~50 digits, so skip this 300 digit test.
160*e1d64b76SMichael Jones // TODO: Create way to test just the first ~50 digits of a number.
161*e1d64b76SMichael Jones #ifndef LIBC_COPT_FLOAT_TO_STR_REDUCED_PRECISION
16283e96977SVinayak Dev     written = func(buff, 499, "%f", 1e300);
16383e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff,
16483e96977SVinayak Dev                      "100000000000000005250476025520442024870446858110815915491"
16583e96977SVinayak Dev                      "585411551180245"
16683e96977SVinayak Dev                      "798890819578637137508044786404370444383288387817694252323"
16783e96977SVinayak Dev                      "536043057564479"
16883e96977SVinayak Dev                      "218478670698284838720092657580373783023379478809005936895"
16983e96977SVinayak Dev                      "323497079994508"
17083e96977SVinayak Dev                      "111903896764088007465274278014249457925878882005684283811"
17183e96977SVinayak Dev                      "566947219638686"
17283e96977SVinayak Dev                      "5459400540160.000000");
173*e1d64b76SMichael Jones #endif // DLIBC_COPT_FLOAT_TO_STR_REDUCED_PRECISION
17483e96977SVinayak Dev 
17583e96977SVinayak Dev     written = func(buff, 99, "%f", 0.1);
17683e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0.100000");
17783e96977SVinayak Dev 
17883e96977SVinayak Dev     written = func(buff, 99, "%f", 1234567890123456789.0);
17983e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1234567890123456768.000000");
18083e96977SVinayak Dev 
18183e96977SVinayak Dev     written = func(buff, 99, "%f", 9999999999999.99);
18283e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "9999999999999.990234");
18383e96977SVinayak Dev 
18483e96977SVinayak Dev     written = func(buff, 99, "%f", 0.1);
18583e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0.100000");
18683e96977SVinayak Dev 
18783e96977SVinayak Dev     written = func(buff, 99, "%f", 1234567890123456789.0);
18883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1234567890123456768.000000");
18983e96977SVinayak Dev 
19083e96977SVinayak Dev     written = func(buff, 99, "%f", 9999999999999.99);
19183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "9999999999999.990234");
19283e96977SVinayak Dev 
19383e96977SVinayak Dev     // Precision Tests
19483e96977SVinayak Dev     written = func(buff, 100, "%.2f", 9999999999999.99);
19583e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "9999999999999.99");
19683e96977SVinayak Dev 
19783e96977SVinayak Dev     written = func(buff, 100, "%.1f", 9999999999999.99);
19883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "10000000000000.0");
19983e96977SVinayak Dev 
20083e96977SVinayak Dev     written = func(buff, 100, "%.5f", 1.25);
20183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.25000");
20283e96977SVinayak Dev 
20383e96977SVinayak Dev     written = func(buff, 100, "%.0f", 1.25);
20483e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1");
20583e96977SVinayak Dev 
20683e96977SVinayak Dev     written = func(buff, 100, "%.20f", 1.234e-10);
20783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0.00000000012340000000");
20883e96977SVinayak Dev   }
20983e96977SVinayak Dev 
21083e96977SVinayak Dev   void floatDecimalLongDoublePrec(FunctionT func) {
21183e96977SVinayak Dev     char buff[45];
21283e96977SVinayak Dev     int written;
21383e96977SVinayak Dev 
21483e96977SVinayak Dev     written = func(buff, 40, "%f", 1.0L);
21583e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.000000");
21683e96977SVinayak Dev 
21783e96977SVinayak Dev     written = func(buff, 10, "%.f", -2.5L);
21883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-2");
21983e96977SVinayak Dev   }
22083e96977SVinayak Dev 
22183e96977SVinayak Dev   void floatHexExpSinglePrec(FunctionT func) {
22283e96977SVinayak Dev     char buff[25];
22383e96977SVinayak Dev     int written;
22483e96977SVinayak Dev 
22583e96977SVinayak Dev     written = func(buff, 0, "%a", 1234567890.0);
22683e96977SVinayak Dev     EXPECT_EQ(written, 14);
22783e96977SVinayak Dev 
22883e96977SVinayak Dev     written = func(buff, 20, "%a", 1234567890.0);
22983e96977SVinayak Dev     EXPECT_EQ(written, 14);
23083e96977SVinayak Dev     ASSERT_STREQ(buff, "0x1.26580cp+30");
23183e96977SVinayak Dev 
23283e96977SVinayak Dev     written = func(buff, 20, "%A", 1234567890.0);
23383e96977SVinayak Dev     EXPECT_EQ(written, 14);
23483e96977SVinayak Dev     ASSERT_STREQ(buff, "0X1.26580CP+30");
23583e96977SVinayak Dev   }
23683e96977SVinayak Dev 
23783e96977SVinayak Dev   void floatHexExpDoublePrec(FunctionT func) {
23883e96977SVinayak Dev     char buff[60];
23983e96977SVinayak Dev     int written;
24083e96977SVinayak Dev 
24183e96977SVinayak Dev     written = func(buff, 10, "%a", 1.0);
24283e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1p+0");
24383e96977SVinayak Dev 
24483e96977SVinayak Dev     written = func(buff, 10, "%A", -1.0);
24583e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-0X1P+0");
24683e96977SVinayak Dev 
24783e96977SVinayak Dev     written = func(buff, 30, "%a", -0x1.abcdef12345p0);
24883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-0x1.abcdef12345p+0");
24983e96977SVinayak Dev 
25083e96977SVinayak Dev     written = func(buff, 50, "%A", 0x1.abcdef12345p0);
25183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0X1.ABCDEF12345P+0");
25283e96977SVinayak Dev 
25383e96977SVinayak Dev     written = func(buff, 10, "%a", 0.0);
25483e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x0p+0");
25583e96977SVinayak Dev 
25683e96977SVinayak Dev     written = func(buff, 40, "%a", 1.0e100);
25783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.249ad2594c37dp+332");
25883e96977SVinayak Dev 
25983e96977SVinayak Dev     written = func(buff, 30, "%a", 0.1);
26083e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.999999999999ap-4");
26183e96977SVinayak Dev   }
26283e96977SVinayak Dev 
26383e96977SVinayak Dev   void floatHexExpLongDoublePrec(FunctionT func) {
26483e96977SVinayak Dev     char buff[55];
26583e96977SVinayak Dev     int written;
26683e96977SVinayak Dev 
26783e96977SVinayak Dev     written = func(buff, 50, "%a", 0.1L);
26883e96977SVinayak Dev #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
26983e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0xc.ccccccccccccccdp-7");
27083e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
27183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.999999999999ap-4");
27283e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
27383e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.999999999999999999999999999ap-4");
27483e96977SVinayak Dev #endif
27583e96977SVinayak Dev 
27683e96977SVinayak Dev     written = func(buff, 20, "%.1a", 0.1L);
27783e96977SVinayak Dev #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
27883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0xc.dp-7");
27983e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
28083e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
28183e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
28283e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.ap-4");
28383e96977SVinayak Dev #endif
28483e96977SVinayak Dev 
28583e96977SVinayak Dev     written = func(buff, 50, "%a", 1.0e1000L);
28683e96977SVinayak Dev #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
28783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0xf.38db1f9dd3dac05p+3318");
28883e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
28983e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "inf");
29083e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
29183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.e71b63f3ba7b580af1a52d2a7379p+3321");
29283e96977SVinayak Dev #endif
29383e96977SVinayak Dev 
29483e96977SVinayak Dev     written = func(buff, 50, "%a", 1.0e-1000L);
29583e96977SVinayak Dev #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
29683e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x8.68a9188a89e1467p-3325");
29783e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
29883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x0p+0");
29983e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
30083e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.0d152311513c28ce202627c06ec2p-3322");
30183e96977SVinayak Dev #endif
30283e96977SVinayak Dev 
30383e96977SVinayak Dev     written = func(buff, 50, "%.1a", 0xf.fffffffffffffffp16380L);
30483e96977SVinayak Dev #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
30583e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x1.0p+16384");
30683e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
30783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "inf");
30883e96977SVinayak Dev #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
30983e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0x2.0p+16383");
31083e96977SVinayak Dev #endif
31183e96977SVinayak Dev   }
31283e96977SVinayak Dev 
31383e96977SVinayak Dev   void floatDecimalExpSinglePrec(FunctionT func) {
31483e96977SVinayak Dev     char buff[25];
31583e96977SVinayak Dev     int written;
31683e96977SVinayak Dev 
31783e96977SVinayak Dev     written = func(buff, 20, "%.9e", 1234567890.0);
31883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.234567936e+09");
31983e96977SVinayak Dev 
32083e96977SVinayak Dev     written = func(buff, 20, "%.9E", 1234567890.0);
32183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.234567936E+09");
32283e96977SVinayak Dev   }
32383e96977SVinayak Dev 
32483e96977SVinayak Dev   void floatDecimalExpDoublePrec(FunctionT func) {
32583e96977SVinayak Dev     char buff[101];
32683e96977SVinayak Dev     int written;
32783e96977SVinayak Dev 
32883e96977SVinayak Dev     written = func(buff, 100, "%e", 1.0);
32983e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.000000e+00");
33083e96977SVinayak Dev 
33183e96977SVinayak Dev     written = func(buff, 100, "%E", -1.0);
33283e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-1.000000E+00");
33383e96977SVinayak Dev 
33483e96977SVinayak Dev     written = func(buff, 100, "%e", -1.234567);
33583e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-1.234567e+00");
33683e96977SVinayak Dev 
33783e96977SVinayak Dev     written = func(buff, 100, "%e", 0.0);
33883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0.000000e+00");
33983e96977SVinayak Dev 
34083e96977SVinayak Dev     written = func(buff, 100, "%e", 1.5);
34183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.500000e+00");
34283e96977SVinayak Dev 
34383e96977SVinayak Dev     written = func(buff, 100, "%e", 1e300);
34483e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.000000e+300");
34583e96977SVinayak Dev 
34683e96977SVinayak Dev     written = func(buff, 100, "%e", 1234567890123456789.0);
34783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.234568e+18");
34883e96977SVinayak Dev 
34983e96977SVinayak Dev     // Precision Tests
35083e96977SVinayak Dev     written = func(buff, 100, "%.1e", 1.0);
35183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.0e+00");
35283e96977SVinayak Dev 
35383e96977SVinayak Dev     written = func(buff, 100, "%.1e", 1.99);
35483e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "2.0e+00");
35583e96977SVinayak Dev 
35683e96977SVinayak Dev     written = func(buff, 100, "%.1e", 9.99);
35783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.0e+01");
35883e96977SVinayak Dev   }
35983e96977SVinayak Dev 
36083e96977SVinayak Dev   void floatDecimalExpLongDoublePrec(FunctionT func) {
3616373577aSVinayak Dev     // Mark as maybe_unused to silence unused variable
3626373577aSVinayak Dev     // warning when long double is not 80-bit
3636373577aSVinayak Dev     [[maybe_unused]] char buff[100];
3646373577aSVinayak Dev     [[maybe_unused]] int written;
36583e96977SVinayak Dev 
36683e96977SVinayak Dev #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
36783e96977SVinayak Dev     written = func(buff, 90, "%.9e", 1000000000500000000.1L);
36883e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.000000001e+18");
36983e96977SVinayak Dev 
37083e96977SVinayak Dev     written = func(buff, 90, "%.9e", 1000000000500000000.0L);
37183e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.000000000e+18");
37283e96977SVinayak Dev 
37383e96977SVinayak Dev     written = func(buff, 90, "%e", 0xf.fffffffffffffffp+16380L);
37483e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.189731e+4932");
37583e96977SVinayak Dev #endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
37683e96977SVinayak Dev   }
37783e96977SVinayak Dev 
37883e96977SVinayak Dev   void floatDecimalAutoSinglePrec(FunctionT func) {
37983e96977SVinayak Dev     char buff[25];
38083e96977SVinayak Dev     int written;
38183e96977SVinayak Dev 
38283e96977SVinayak Dev     written = func(buff, 20, "%.9g", 1234567890.0);
38383e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.23456794e+09");
38483e96977SVinayak Dev 
38583e96977SVinayak Dev     written = func(buff, 20, "%.9G", 1234567890.0);
38683e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.23456794E+09");
38783e96977SVinayak Dev   }
38883e96977SVinayak Dev 
38983e96977SVinayak Dev   void floatDecimalAutoDoublePrec(FunctionT func) {
39083e96977SVinayak Dev     char buff[120];
39183e96977SVinayak Dev     int written;
39283e96977SVinayak Dev 
39383e96977SVinayak Dev     written = func(buff, 100, "%g", 1234567890123456789.0);
39483e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.23457e+18");
39583e96977SVinayak Dev 
39683e96977SVinayak Dev     written = func(buff, 100, "%g", 9999990000000.00);
39783e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "9.99999e+12");
39883e96977SVinayak Dev 
39983e96977SVinayak Dev     written = func(buff, 100, "%g", 9999999000000.00);
40083e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1e+13");
40183e96977SVinayak Dev 
40283e96977SVinayak Dev     written = func(buff, 100, "%g", 0xa.aaaaaaaaaaaaaabp-7);
40383e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0.0833333");
40483e96977SVinayak Dev 
40583e96977SVinayak Dev     written = func(buff, 100, "%g", 0.00001);
40683e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1e-05");
40783e96977SVinayak Dev 
40883e96977SVinayak Dev     // Precision Tests
40983e96977SVinayak Dev     written = func(buff, 100, "%.0g", 0.0);
41083e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0");
41183e96977SVinayak Dev 
41283e96977SVinayak Dev     written = func(buff, 100, "%.2g", 0.1);
41383e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0.1");
41483e96977SVinayak Dev 
41583e96977SVinayak Dev     written = func(buff, 100, "%.2g", 1.09);
41683e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.1");
41783e96977SVinayak Dev 
41883e96977SVinayak Dev     written = func(buff, 100, "%.15g", 22.25);
41983e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "22.25");
42083e96977SVinayak Dev 
42183e96977SVinayak Dev     written = func(buff, 100, "%.20g", 1.234e-10);
42283e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.2340000000000000814e-10");
42383e96977SVinayak Dev   }
42483e96977SVinayak Dev 
42583e96977SVinayak Dev   void floatDecimalAutoLongDoublePrec(FunctionT func) {
4266373577aSVinayak Dev     // Mark as maybe_unused to silence unused variable
4276373577aSVinayak Dev     // warning when long double is not 80-bit
4286373577aSVinayak Dev     [[maybe_unused]] char buff[100];
4296373577aSVinayak Dev     [[maybe_unused]] int written;
43083e96977SVinayak Dev 
43183e96977SVinayak Dev #if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
43283e96977SVinayak Dev     written = func(buff, 99, "%g", 0xf.fffffffffffffffp+16380L);
43383e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1.18973e+4932");
43483e96977SVinayak Dev 
43583e96977SVinayak Dev     written = func(buff, 99, "%g", 0xa.aaaaaaaaaaaaaabp-7L);
43683e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "0.0833333");
43783e96977SVinayak Dev 
43883e96977SVinayak Dev     written = func(buff, 99, "%g", 9.99999999999e-100L);
43983e96977SVinayak Dev     ASSERT_STREQ_LEN(written, buff, "1e-99");
44083e96977SVinayak Dev #endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
44183e96977SVinayak Dev   }
4426373577aSVinayak Dev 
4436373577aSVinayak Dev   void doublePrecInfNan(FunctionT func) {
4446373577aSVinayak Dev     char buff[15];
4456373577aSVinayak Dev     int written;
4466373577aSVinayak Dev 
4476373577aSVinayak Dev     double inf = LIBC_NAMESPACE::fputil::FPBits<double>::inf().get_val();
4486373577aSVinayak Dev     double nan = LIBC_NAMESPACE::fputil::FPBits<double>::quiet_nan().get_val();
4496373577aSVinayak Dev 
4506373577aSVinayak Dev     written = func(buff, 10, "%f", inf);
4516373577aSVinayak Dev     ASSERT_STREQ_LEN(written, buff, "inf");
4526373577aSVinayak Dev 
4536373577aSVinayak Dev     written = func(buff, 10, "%A", -inf);
4546373577aSVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-INF");
4556373577aSVinayak Dev 
4566373577aSVinayak Dev     written = func(buff, 10, "%f", nan);
4576373577aSVinayak Dev     ASSERT_STREQ_LEN(written, buff, "nan");
4586373577aSVinayak Dev 
4596373577aSVinayak Dev     written = func(buff, 10, "%A", -nan);
4606373577aSVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-NAN");
4616373577aSVinayak Dev   }
4626373577aSVinayak Dev 
4636373577aSVinayak Dev   void longDoublePrecInfNan(FunctionT func) {
4646373577aSVinayak Dev     char buff[15];
4656373577aSVinayak Dev     int written;
4666373577aSVinayak Dev 
4676373577aSVinayak Dev     long double ld_inf =
4686373577aSVinayak Dev         LIBC_NAMESPACE::fputil::FPBits<long double>::inf().get_val();
4696373577aSVinayak Dev     long double ld_nan =
4706373577aSVinayak Dev         LIBC_NAMESPACE::fputil::FPBits<long double>::quiet_nan().get_val();
4716373577aSVinayak Dev 
4726373577aSVinayak Dev     written = func(buff, 10, "%f", ld_inf);
4736373577aSVinayak Dev     ASSERT_STREQ_LEN(written, buff, "inf");
4746373577aSVinayak Dev 
4756373577aSVinayak Dev     written = func(buff, 10, "%A", -ld_inf);
4766373577aSVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-INF");
4776373577aSVinayak Dev 
4786373577aSVinayak Dev     written = func(buff, 10, "%f", ld_nan);
4796373577aSVinayak Dev     ASSERT_STREQ_LEN(written, buff, "nan");
4806373577aSVinayak Dev 
4816373577aSVinayak Dev     written = func(buff, 10, "%A", -ld_nan);
4826373577aSVinayak Dev     ASSERT_STREQ_LEN(written, buff, "-NAN");
4836373577aSVinayak Dev   }
48483e96977SVinayak Dev };
48583e96977SVinayak Dev 
48683e96977SVinayak Dev #define STRFROM_TEST(InputType, name, func)                                    \
48783e96977SVinayak Dev   using LlvmLibc##name##Test = StrfromTest<InputType>;                         \
48883e96977SVinayak Dev   TEST_F(LlvmLibc##name##Test, FloatDecimalFormat) {                           \
48983e96977SVinayak Dev     floatDecimalFormat(func);                                                  \
49083e96977SVinayak Dev   }                                                                            \
49183e96977SVinayak Dev   TEST_F(LlvmLibc##name##Test, FloatHexExpFormat) { floatHexExpFormat(func); } \
49283e96977SVinayak Dev   TEST_F(LlvmLibc##name##Test, FloatDecimalAutoFormat) {                       \
49383e96977SVinayak Dev     floatDecimalAutoFormat(func);                                              \
49483e96977SVinayak Dev   }                                                                            \
49583e96977SVinayak Dev   TEST_F(LlvmLibc##name##Test, FloatDecimalExpFormat) {                        \
49683e96977SVinayak Dev     floatDecimalExpFormat(func);                                               \
49783e96977SVinayak Dev   }                                                                            \
49883e96977SVinayak Dev   TEST_F(LlvmLibc##name##Test, ImproperFormatString) {                         \
49983e96977SVinayak Dev     improperFormatString(func);                                                \
50083e96977SVinayak Dev   }                                                                            \
50183e96977SVinayak Dev   TEST_F(LlvmLibc##name##Test, InsufficientBufferSize) {                       \
50283e96977SVinayak Dev     insufficentBufsize(func);                                                  \
5036373577aSVinayak Dev   }                                                                            \
5046373577aSVinayak Dev   TEST_F(LlvmLibc##name##Test, InfAndNanValues) { infNanValues(func); }
505