1*5c90c05cSAndroid Build Coastguard Worker // Formatting library for C++ - printf tests
2*5c90c05cSAndroid Build Coastguard Worker //
3*5c90c05cSAndroid Build Coastguard Worker // Copyright (c) 2012 - present, Victor Zverovich
4*5c90c05cSAndroid Build Coastguard Worker // All rights reserved.
5*5c90c05cSAndroid Build Coastguard Worker //
6*5c90c05cSAndroid Build Coastguard Worker // For the license information refer to format.h.
7*5c90c05cSAndroid Build Coastguard Worker
8*5c90c05cSAndroid Build Coastguard Worker #include "fmt/printf.h"
9*5c90c05cSAndroid Build Coastguard Worker // include <format> if possible for https://github.com/fmtlib/fmt/pull/4042
10*5c90c05cSAndroid Build Coastguard Worker #if FMT_HAS_INCLUDE(<format>) && FMT_CPLUSPLUS > 201703L
11*5c90c05cSAndroid Build Coastguard Worker # include <format>
12*5c90c05cSAndroid Build Coastguard Worker #endif
13*5c90c05cSAndroid Build Coastguard Worker
14*5c90c05cSAndroid Build Coastguard Worker #include <cctype>
15*5c90c05cSAndroid Build Coastguard Worker #include <climits>
16*5c90c05cSAndroid Build Coastguard Worker #include <cstring>
17*5c90c05cSAndroid Build Coastguard Worker
18*5c90c05cSAndroid Build Coastguard Worker #include "fmt/xchar.h"
19*5c90c05cSAndroid Build Coastguard Worker #include "gtest-extra.h"
20*5c90c05cSAndroid Build Coastguard Worker #include "util.h"
21*5c90c05cSAndroid Build Coastguard Worker
22*5c90c05cSAndroid Build Coastguard Worker using fmt::format;
23*5c90c05cSAndroid Build Coastguard Worker using fmt::format_error;
24*5c90c05cSAndroid Build Coastguard Worker using fmt::detail::max_value;
25*5c90c05cSAndroid Build Coastguard Worker
26*5c90c05cSAndroid Build Coastguard Worker const unsigned big_num = INT_MAX + 1u;
27*5c90c05cSAndroid Build Coastguard Worker
28*5c90c05cSAndroid Build Coastguard Worker // Makes format string argument positional.
make_positional(fmt::string_view format)29*5c90c05cSAndroid Build Coastguard Worker static std::string make_positional(fmt::string_view format) {
30*5c90c05cSAndroid Build Coastguard Worker std::string s(format.data(), format.size());
31*5c90c05cSAndroid Build Coastguard Worker s.replace(s.find('%'), 1, "%1$");
32*5c90c05cSAndroid Build Coastguard Worker return s;
33*5c90c05cSAndroid Build Coastguard Worker }
34*5c90c05cSAndroid Build Coastguard Worker
make_positional(fmt::basic_string_view<wchar_t> format)35*5c90c05cSAndroid Build Coastguard Worker static std::wstring make_positional(fmt::basic_string_view<wchar_t> format) {
36*5c90c05cSAndroid Build Coastguard Worker std::wstring s(format.data(), format.size());
37*5c90c05cSAndroid Build Coastguard Worker s.replace(s.find(L'%'), 1, L"%1$");
38*5c90c05cSAndroid Build Coastguard Worker return s;
39*5c90c05cSAndroid Build Coastguard Worker }
40*5c90c05cSAndroid Build Coastguard Worker
41*5c90c05cSAndroid Build Coastguard Worker // A wrapper around fmt::sprintf to workaround bogus warnings about invalid
42*5c90c05cSAndroid Build Coastguard Worker // format strings in MSVC.
43*5c90c05cSAndroid Build Coastguard Worker template <typename... Args>
test_sprintf(fmt::string_view format,const Args &...args)44*5c90c05cSAndroid Build Coastguard Worker std::string test_sprintf(fmt::string_view format, const Args&... args) {
45*5c90c05cSAndroid Build Coastguard Worker return fmt::sprintf(format, args...);
46*5c90c05cSAndroid Build Coastguard Worker }
47*5c90c05cSAndroid Build Coastguard Worker template <typename... Args>
test_sprintf(fmt::basic_string_view<wchar_t> format,const Args &...args)48*5c90c05cSAndroid Build Coastguard Worker std::wstring test_sprintf(fmt::basic_string_view<wchar_t> format,
49*5c90c05cSAndroid Build Coastguard Worker const Args&... args) {
50*5c90c05cSAndroid Build Coastguard Worker return fmt::sprintf(format, args...);
51*5c90c05cSAndroid Build Coastguard Worker }
52*5c90c05cSAndroid Build Coastguard Worker
53*5c90c05cSAndroid Build Coastguard Worker #define EXPECT_PRINTF(expected_output, format, arg) \
54*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(expected_output, test_sprintf(format, arg)) \
55*5c90c05cSAndroid Build Coastguard Worker << "format: " << format; \
56*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(expected_output, fmt::sprintf(make_positional(format), arg))
57*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,no_args)58*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, no_args) {
59*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("test", test_sprintf("test"));
60*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(L"test", fmt::sprintf(L"test"));
61*5c90c05cSAndroid Build Coastguard Worker }
62*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,escape)63*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, escape) {
64*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("%", test_sprintf("%%"));
65*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("before %", test_sprintf("before %%"));
66*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("% after", test_sprintf("%% after"));
67*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("before % after", test_sprintf("before %% after"));
68*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("%s", test_sprintf("%%s"));
69*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(L"%", fmt::sprintf(L"%%"));
70*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(L"before %", fmt::sprintf(L"before %%"));
71*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(L"% after", fmt::sprintf(L"%% after"));
72*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(L"before % after", fmt::sprintf(L"before %% after"));
73*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(L"%s", fmt::sprintf(L"%%s"));
74*5c90c05cSAndroid Build Coastguard Worker }
75*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,positional_args)76*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, positional_args) {
77*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("42", test_sprintf("%1$d", 42));
78*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("before 42", test_sprintf("before %1$d", 42));
79*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("42 after", test_sprintf("%1$d after", 42));
80*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("before 42 after", test_sprintf("before %1$d after", 42));
81*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("answer = 42", test_sprintf("%1$s = %2$d", "answer", 42));
82*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("42 is the answer", test_sprintf("%2$d is the %1$s", "answer", 42));
83*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("abracadabra", test_sprintf("%1$s%2$s%1$s", "abra", "cad"));
84*5c90c05cSAndroid Build Coastguard Worker }
85*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,automatic_arg_indexing)86*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, automatic_arg_indexing) {
87*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("abc", test_sprintf("%c%c%c", 'a', 'b', 'c'));
88*5c90c05cSAndroid Build Coastguard Worker }
89*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,number_is_too_big_in_arg_index)90*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, number_is_too_big_in_arg_index) {
91*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%{}$", big_num)), format_error,
92*5c90c05cSAndroid Build Coastguard Worker "argument not found");
93*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%{}$d", big_num)), format_error,
94*5c90c05cSAndroid Build Coastguard Worker "argument not found");
95*5c90c05cSAndroid Build Coastguard Worker }
96*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,switch_arg_indexing)97*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, switch_arg_indexing) {
98*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%1$d%", 1, 2), format_error,
99*5c90c05cSAndroid Build Coastguard Worker "cannot switch from manual to automatic argument indexing");
100*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", big_num), 1, 2),
101*5c90c05cSAndroid Build Coastguard Worker format_error, "number is too big");
102*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%1$d%d", 1, 2), format_error,
103*5c90c05cSAndroid Build Coastguard Worker "cannot switch from manual to automatic argument indexing");
104*5c90c05cSAndroid Build Coastguard Worker
105*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%d%1$", 1, 2), format_error,
106*5c90c05cSAndroid Build Coastguard Worker "cannot switch from automatic to manual argument indexing");
107*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%d%{}$d", big_num), 1, 2), format_error,
108*5c90c05cSAndroid Build Coastguard Worker "cannot switch from automatic to manual argument indexing");
109*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%d%1$d", 1, 2), format_error,
110*5c90c05cSAndroid Build Coastguard Worker "cannot switch from automatic to manual argument indexing");
111*5c90c05cSAndroid Build Coastguard Worker
112*5c90c05cSAndroid Build Coastguard Worker // Indexing errors override width errors.
113*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%d%1${}d", big_num), 1, 2),
114*5c90c05cSAndroid Build Coastguard Worker format_error, "number is too big");
115*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", big_num), 1, 2),
116*5c90c05cSAndroid Build Coastguard Worker format_error, "number is too big");
117*5c90c05cSAndroid Build Coastguard Worker }
118*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,invalid_arg_index)119*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, invalid_arg_index) {
120*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%0$d", 42), format_error,
121*5c90c05cSAndroid Build Coastguard Worker "argument not found");
122*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%2$d", 42), format_error,
123*5c90c05cSAndroid Build Coastguard Worker "argument not found");
124*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%{}$d", INT_MAX), 42), format_error,
125*5c90c05cSAndroid Build Coastguard Worker "argument not found");
126*5c90c05cSAndroid Build Coastguard Worker
127*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%2$", 42), format_error, "argument not found");
128*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%{}$d", big_num), 42), format_error,
129*5c90c05cSAndroid Build Coastguard Worker "argument not found");
130*5c90c05cSAndroid Build Coastguard Worker }
131*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,default_align_right)132*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, default_align_right) {
133*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 42", "%5d", 42);
134*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" abc", "%5s", "abc");
135*5c90c05cSAndroid Build Coastguard Worker }
136*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,zero_flag)137*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, zero_flag) {
138*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042", "%05d", 42);
139*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-0042", "%05d", -42);
140*5c90c05cSAndroid Build Coastguard Worker
141*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042", "%05d", 42);
142*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-0042", "%05d", -42);
143*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-004.2", "%06g", -4.2);
144*5c90c05cSAndroid Build Coastguard Worker
145*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("+00042", "%00+6d", 42);
146*5c90c05cSAndroid Build Coastguard Worker
147*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 42", "%05.d", 42);
148*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 0042", "%05.4d", 42);
149*5c90c05cSAndroid Build Coastguard Worker
150*5c90c05cSAndroid Build Coastguard Worker // '0' flag is ignored for non-numeric types.
151*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" x", "%05c", 'x');
152*5c90c05cSAndroid Build Coastguard Worker }
153*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,plus_flag)154*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, plus_flag) {
155*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("+42", "%+d", 42);
156*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42", "%+d", -42);
157*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("+0042", "%+05d", 42);
158*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("+0042", "%0++5d", 42);
159*5c90c05cSAndroid Build Coastguard Worker
160*5c90c05cSAndroid Build Coastguard Worker // '+' flag is ignored for non-numeric types.
161*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("x", "%+c", 'x');
162*5c90c05cSAndroid Build Coastguard Worker
163*5c90c05cSAndroid Build Coastguard Worker // '+' flag wins over space flag
164*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("+42", "%+ d", 42);
165*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42", "%+ d", -42);
166*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("+42", "% +d", 42);
167*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42", "% +d", -42);
168*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("+0042", "% +05d", 42);
169*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("+0042", "%0+ 5d", 42);
170*5c90c05cSAndroid Build Coastguard Worker
171*5c90c05cSAndroid Build Coastguard Worker // '+' flag and space flag are both ignored for non-numeric types.
172*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("x", "%+ c", 'x');
173*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("x", "% +c", 'x');
174*5c90c05cSAndroid Build Coastguard Worker }
175*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,minus_flag)176*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, minus_flag) {
177*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("abc ", "%-5s", "abc");
178*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("abc ", "%0--5s", "abc");
179*5c90c05cSAndroid Build Coastguard Worker
180*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("7 ", "%-5d", 7);
181*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("97 ", "%-5hhi", 'a');
182*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("a ", "%-5c", 'a');
183*5c90c05cSAndroid Build Coastguard Worker
184*5c90c05cSAndroid Build Coastguard Worker // '0' flag is ignored if '-' flag is given
185*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("7 ", "%-05d", 7);
186*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("7 ", "%0-5d", 7);
187*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("a ", "%-05c", 'a');
188*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("a ", "%0-5c", 'a');
189*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("97 ", "%-05hhi", 'a');
190*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("97 ", "%0-5hhi", 'a');
191*5c90c05cSAndroid Build Coastguard Worker
192*5c90c05cSAndroid Build Coastguard Worker // '-' and space flag don't interfere
193*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 42", "%- d", 42);
194*5c90c05cSAndroid Build Coastguard Worker }
195*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,space_flag)196*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, space_flag) {
197*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 42", "% d", 42);
198*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42", "% d", -42);
199*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 0042", "% 05d", 42);
200*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 0042", "%0 5d", 42);
201*5c90c05cSAndroid Build Coastguard Worker
202*5c90c05cSAndroid Build Coastguard Worker // ' ' flag is ignored for non-numeric types.
203*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("x", "% c", 'x');
204*5c90c05cSAndroid Build Coastguard Worker }
205*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,hash_flag)206*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, hash_flag) {
207*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("042", "%#o", 042);
208*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("0{:o}", static_cast<unsigned>(-042)), "%#o", -042);
209*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0", "%#o", 0);
210*5c90c05cSAndroid Build Coastguard Worker
211*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0x42", "%#x", 0x42);
212*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0X42", "%#X", 0x42);
213*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("0x{:x}", static_cast<unsigned>(-0x42)), "%#x",
214*5c90c05cSAndroid Build Coastguard Worker -0x42);
215*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0", "%#x", 0);
216*5c90c05cSAndroid Build Coastguard Worker
217*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0x0042", "%#06x", 0x42);
218*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0x0042", "%0##6x", 0x42);
219*5c90c05cSAndroid Build Coastguard Worker
220*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42.000000", "%#f", -42.0);
221*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42.000000", "%#F", -42.0);
222*5c90c05cSAndroid Build Coastguard Worker
223*5c90c05cSAndroid Build Coastguard Worker char buffer[256];
224*5c90c05cSAndroid Build Coastguard Worker safe_sprintf(buffer, "%#e", -42.0);
225*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(buffer, "%#e", -42.0);
226*5c90c05cSAndroid Build Coastguard Worker safe_sprintf(buffer, "%#E", -42.0);
227*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(buffer, "%#E", -42.0);
228*5c90c05cSAndroid Build Coastguard Worker
229*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42.0000", "%#g", -42.0);
230*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42.0000", "%#G", -42.0);
231*5c90c05cSAndroid Build Coastguard Worker
232*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0x1.p+4", "%#a", 16.0);
233*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0X1.P+4", "%#A", 16.0);
234*5c90c05cSAndroid Build Coastguard Worker
235*5c90c05cSAndroid Build Coastguard Worker // '#' flag is ignored for non-numeric types.
236*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("x", "%#c", 'x');
237*5c90c05cSAndroid Build Coastguard Worker }
238*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,width)239*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, width) {
240*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" abc", "%5s", "abc");
241*5c90c05cSAndroid Build Coastguard Worker
242*5c90c05cSAndroid Build Coastguard Worker // Width cannot be specified twice.
243*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%5-5d", 42), format_error,
244*5c90c05cSAndroid Build Coastguard Worker "invalid format specifier");
245*5c90c05cSAndroid Build Coastguard Worker
246*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%{}d", big_num), 42), format_error,
247*5c90c05cSAndroid Build Coastguard Worker "number is too big");
248*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf(format("%1${}d", big_num), 42), format_error,
249*5c90c05cSAndroid Build Coastguard Worker "number is too big");
250*5c90c05cSAndroid Build Coastguard Worker }
251*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,dynamic_width)252*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, dynamic_width) {
253*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(" 42", test_sprintf("%*d", 5, 42));
254*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("42 ", test_sprintf("%*d", -5, 42));
255*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%*d", 5.0, 42), format_error,
256*5c90c05cSAndroid Build Coastguard Worker "width is not integer");
257*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%*d"), format_error, "argument not found");
258*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%*d", big_num, 42), format_error,
259*5c90c05cSAndroid Build Coastguard Worker "number is too big");
260*5c90c05cSAndroid Build Coastguard Worker }
261*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,int_precision)262*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, int_precision) {
263*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042", "%.5d", 42);
264*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-00042", "%.5d", -42);
265*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042", "%.5x", 0x42);
266*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0x00042", "%#.5x", 0x42);
267*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042", "%.5o", 042);
268*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042", "%#.5o", 042);
269*5c90c05cSAndroid Build Coastguard Worker
270*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 00042", "%7.5d", 42);
271*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 00042", "%7.5x", 0x42);
272*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 0x00042", "%#10.5x", 0x42);
273*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 00042", "%7.5o", 042);
274*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" 00042", "%#10.5o", 042);
275*5c90c05cSAndroid Build Coastguard Worker
276*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042 ", "%-7.5d", 42);
277*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042 ", "%-7.5x", 0x42);
278*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("0x00042 ", "%-#10.5x", 0x42);
279*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042 ", "%-7.5o", 042);
280*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("00042 ", "%-#10.5o", 042);
281*5c90c05cSAndroid Build Coastguard Worker }
282*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,float_precision)283*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, float_precision) {
284*5c90c05cSAndroid Build Coastguard Worker char buffer[256];
285*5c90c05cSAndroid Build Coastguard Worker safe_sprintf(buffer, "%.3e", 1234.5678);
286*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(buffer, "%.3e", 1234.5678);
287*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("1234.568", "%.3f", 1234.5678);
288*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("1.23e+03", "%.3g", 1234.5678);
289*5c90c05cSAndroid Build Coastguard Worker safe_sprintf(buffer, "%.3a", 1234.5678);
290*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(buffer, "%.3a", 1234.5678);
291*5c90c05cSAndroid Build Coastguard Worker }
292*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,string_precision)293*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, string_precision) {
294*5c90c05cSAndroid Build Coastguard Worker char test[] = {'H', 'e', 'l', 'l', 'o'};
295*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(fmt::sprintf("%.4s", test), "Hell");
296*5c90c05cSAndroid Build Coastguard Worker }
297*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,ignore_precision_for_non_numeric_arg)298*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, ignore_precision_for_non_numeric_arg) {
299*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("abc", "%.5s", "abc");
300*5c90c05cSAndroid Build Coastguard Worker }
301*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,dynamic_precision)302*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, dynamic_precision) {
303*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("00042", test_sprintf("%.*d", 5, 42));
304*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("42", test_sprintf("%.*d", -5, 42));
305*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%.*d", 5.0, 42), format_error,
306*5c90c05cSAndroid Build Coastguard Worker "precision is not integer");
307*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%.*d"), format_error, "argument not found");
308*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%.*d", big_num, 42), format_error,
309*5c90c05cSAndroid Build Coastguard Worker "number is too big");
310*5c90c05cSAndroid Build Coastguard Worker if (sizeof(long long) != sizeof(int)) {
311*5c90c05cSAndroid Build Coastguard Worker long long prec = static_cast<long long>(INT_MIN) - 1;
312*5c90c05cSAndroid Build Coastguard Worker EXPECT_THROW_MSG(test_sprintf("%.*d", prec, 42), format_error,
313*5c90c05cSAndroid Build Coastguard Worker "number is too big");
314*5c90c05cSAndroid Build Coastguard Worker }
315*5c90c05cSAndroid Build Coastguard Worker }
316*5c90c05cSAndroid Build Coastguard Worker
317*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct make_signed {
318*5c90c05cSAndroid Build Coastguard Worker using type = T;
319*5c90c05cSAndroid Build Coastguard Worker };
320*5c90c05cSAndroid Build Coastguard Worker
321*5c90c05cSAndroid Build Coastguard Worker #define SPECIALIZE_MAKE_SIGNED(T, S) \
322*5c90c05cSAndroid Build Coastguard Worker template <> struct make_signed<T> { \
323*5c90c05cSAndroid Build Coastguard Worker using type = S; \
324*5c90c05cSAndroid Build Coastguard Worker }
325*5c90c05cSAndroid Build Coastguard Worker
326*5c90c05cSAndroid Build Coastguard Worker SPECIALIZE_MAKE_SIGNED(char, signed char);
327*5c90c05cSAndroid Build Coastguard Worker SPECIALIZE_MAKE_SIGNED(unsigned char, signed char);
328*5c90c05cSAndroid Build Coastguard Worker SPECIALIZE_MAKE_SIGNED(unsigned short, short);
329*5c90c05cSAndroid Build Coastguard Worker SPECIALIZE_MAKE_SIGNED(unsigned, int);
330*5c90c05cSAndroid Build Coastguard Worker SPECIALIZE_MAKE_SIGNED(unsigned long, long);
331*5c90c05cSAndroid Build Coastguard Worker SPECIALIZE_MAKE_SIGNED(unsigned long long, long long);
332*5c90c05cSAndroid Build Coastguard Worker
333*5c90c05cSAndroid Build Coastguard Worker // Test length format specifier ``length_spec``.
334*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename U>
test_length(const char * length_spec,U value)335*5c90c05cSAndroid Build Coastguard Worker void test_length(const char* length_spec, U value) {
336*5c90c05cSAndroid Build Coastguard Worker long long signed_value = 0;
337*5c90c05cSAndroid Build Coastguard Worker unsigned long long unsigned_value = 0;
338*5c90c05cSAndroid Build Coastguard Worker // Apply integer promotion to the argument.
339*5c90c05cSAndroid Build Coastguard Worker unsigned long long max = max_value<U>();
340*5c90c05cSAndroid Build Coastguard Worker using fmt::detail::const_check;
341*5c90c05cSAndroid Build Coastguard Worker if (const_check(max <= static_cast<unsigned>(max_value<int>()))) {
342*5c90c05cSAndroid Build Coastguard Worker signed_value = static_cast<int>(value);
343*5c90c05cSAndroid Build Coastguard Worker unsigned_value = static_cast<unsigned long long>(value);
344*5c90c05cSAndroid Build Coastguard Worker } else if (const_check(max <= max_value<unsigned>())) {
345*5c90c05cSAndroid Build Coastguard Worker signed_value = static_cast<unsigned>(value);
346*5c90c05cSAndroid Build Coastguard Worker unsigned_value = static_cast<unsigned long long>(value);
347*5c90c05cSAndroid Build Coastguard Worker }
348*5c90c05cSAndroid Build Coastguard Worker if (sizeof(U) <= sizeof(int) && sizeof(int) < sizeof(T)) {
349*5c90c05cSAndroid Build Coastguard Worker signed_value = static_cast<long long>(value);
350*5c90c05cSAndroid Build Coastguard Worker unsigned_value = static_cast<unsigned long long>(
351*5c90c05cSAndroid Build Coastguard Worker static_cast<typename std::make_unsigned<unsigned>::type>(value));
352*5c90c05cSAndroid Build Coastguard Worker } else {
353*5c90c05cSAndroid Build Coastguard Worker signed_value = static_cast<typename make_signed<T>::type>(value);
354*5c90c05cSAndroid Build Coastguard Worker unsigned_value = static_cast<typename std::make_unsigned<T>::type>(value);
355*5c90c05cSAndroid Build Coastguard Worker }
356*5c90c05cSAndroid Build Coastguard Worker std::ostringstream os;
357*5c90c05cSAndroid Build Coastguard Worker os << signed_value;
358*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(os.str(), fmt::format("%{}d", length_spec), value);
359*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(os.str(), fmt::format("%{}i", length_spec), value);
360*5c90c05cSAndroid Build Coastguard Worker os.str("");
361*5c90c05cSAndroid Build Coastguard Worker os << unsigned_value;
362*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(os.str(), fmt::format("%{}u", length_spec), value);
363*5c90c05cSAndroid Build Coastguard Worker os.str("");
364*5c90c05cSAndroid Build Coastguard Worker os << std::oct << unsigned_value;
365*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(os.str(), fmt::format("%{}o", length_spec), value);
366*5c90c05cSAndroid Build Coastguard Worker os.str("");
367*5c90c05cSAndroid Build Coastguard Worker os << std::hex << unsigned_value;
368*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(os.str(), fmt::format("%{}x", length_spec), value);
369*5c90c05cSAndroid Build Coastguard Worker os.str("");
370*5c90c05cSAndroid Build Coastguard Worker os << std::hex << std::uppercase << unsigned_value;
371*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(os.str(), fmt::format("%{}X", length_spec), value);
372*5c90c05cSAndroid Build Coastguard Worker }
373*5c90c05cSAndroid Build Coastguard Worker
test_length(const char * length_spec)374*5c90c05cSAndroid Build Coastguard Worker template <typename T> void test_length(const char* length_spec) {
375*5c90c05cSAndroid Build Coastguard Worker T min = std::numeric_limits<T>::min(), max = max_value<T>();
376*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, 42);
377*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, -42);
378*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, min);
379*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, max);
380*5c90c05cSAndroid Build Coastguard Worker long long long_long_min = std::numeric_limits<long long>::min();
381*5c90c05cSAndroid Build Coastguard Worker if (static_cast<long long>(min) > long_long_min)
382*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, static_cast<long long>(min) - 1);
383*5c90c05cSAndroid Build Coastguard Worker unsigned long long long_long_max = max_value<long long>();
384*5c90c05cSAndroid Build Coastguard Worker if (static_cast<unsigned long long>(max) < long_long_max)
385*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, static_cast<long long>(max) + 1);
386*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, std::numeric_limits<short>::min());
387*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, max_value<unsigned short>());
388*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, std::numeric_limits<int>::min());
389*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, max_value<int>());
390*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, std::numeric_limits<unsigned>::min());
391*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, max_value<unsigned>());
392*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, std::numeric_limits<long long>::min());
393*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, max_value<long long>());
394*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, std::numeric_limits<unsigned long long>::min());
395*5c90c05cSAndroid Build Coastguard Worker test_length<T>(length_spec, max_value<unsigned long long>());
396*5c90c05cSAndroid Build Coastguard Worker }
397*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,length)398*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, length) {
399*5c90c05cSAndroid Build Coastguard Worker test_length<char>("hh");
400*5c90c05cSAndroid Build Coastguard Worker test_length<signed char>("hh");
401*5c90c05cSAndroid Build Coastguard Worker test_length<unsigned char>("hh");
402*5c90c05cSAndroid Build Coastguard Worker test_length<short>("h");
403*5c90c05cSAndroid Build Coastguard Worker test_length<unsigned short>("h");
404*5c90c05cSAndroid Build Coastguard Worker test_length<long>("l");
405*5c90c05cSAndroid Build Coastguard Worker test_length<unsigned long>("l");
406*5c90c05cSAndroid Build Coastguard Worker test_length<long long>("ll");
407*5c90c05cSAndroid Build Coastguard Worker test_length<unsigned long long>("ll");
408*5c90c05cSAndroid Build Coastguard Worker test_length<intmax_t>("j");
409*5c90c05cSAndroid Build Coastguard Worker test_length<size_t>("z");
410*5c90c05cSAndroid Build Coastguard Worker test_length<std::ptrdiff_t>("t");
411*5c90c05cSAndroid Build Coastguard Worker long double max = max_value<long double>();
412*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{:.6}", max), "%g", max);
413*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{:.6}", max), "%Lg", max);
414*5c90c05cSAndroid Build Coastguard Worker }
415*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,bool)416*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, bool) { EXPECT_PRINTF("1", "%d", true); }
417*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,int)418*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, int) {
419*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42", "%d", -42);
420*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("-42", "%i", -42);
421*5c90c05cSAndroid Build Coastguard Worker unsigned u = 0 - 42u;
422*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{}", u), "%u", -42);
423*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{:o}", u), "%o", -42);
424*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{:x}", u), "%x", -42);
425*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{:X}", u), "%X", -42);
426*5c90c05cSAndroid Build Coastguard Worker }
427*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,long_long)428*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, long_long) {
429*5c90c05cSAndroid Build Coastguard Worker // fmt::printf allows passing long long arguments to %d without length
430*5c90c05cSAndroid Build Coastguard Worker // specifiers.
431*5c90c05cSAndroid Build Coastguard Worker long long max = max_value<long long>();
432*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{}", max), "%d", max);
433*5c90c05cSAndroid Build Coastguard Worker }
434*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,float)435*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, float) {
436*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("392.650000", "%f", 392.65);
437*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("392.65", "%.2f", 392.65);
438*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("392.6", "%.1f", 392.65);
439*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("393", "%.f", 392.65);
440*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("392.650000", "%F", 392.65);
441*5c90c05cSAndroid Build Coastguard Worker char buffer[256];
442*5c90c05cSAndroid Build Coastguard Worker safe_sprintf(buffer, "%e", 392.65);
443*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(buffer, "%e", 392.65);
444*5c90c05cSAndroid Build Coastguard Worker safe_sprintf(buffer, "%E", 392.65);
445*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(buffer, "%E", 392.65);
446*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("392.65", "%g", 392.65);
447*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("392.65", "%G", 392.65);
448*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("392", "%g", 392.0);
449*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("392", "%G", 392.0);
450*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("4.56e-07", "%g", 0.000000456);
451*5c90c05cSAndroid Build Coastguard Worker safe_sprintf(buffer, "%a", -392.65);
452*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(buffer, format("{:a}", -392.65));
453*5c90c05cSAndroid Build Coastguard Worker safe_sprintf(buffer, "%A", -392.65);
454*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(buffer, format("{:A}", -392.65));
455*5c90c05cSAndroid Build Coastguard Worker }
456*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,inf)457*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, inf) {
458*5c90c05cSAndroid Build Coastguard Worker double inf = std::numeric_limits<double>::infinity();
459*5c90c05cSAndroid Build Coastguard Worker for (const char* type = "fega"; *type; ++type) {
460*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("inf", fmt::format("%{}", *type), inf);
461*5c90c05cSAndroid Build Coastguard Worker char upper = static_cast<char>(std::toupper(*type));
462*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("INF", fmt::format("%{}", upper), inf);
463*5c90c05cSAndroid Build Coastguard Worker }
464*5c90c05cSAndroid Build Coastguard Worker }
465*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,char)466*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, char) {
467*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("x", "%c", 'x');
468*5c90c05cSAndroid Build Coastguard Worker int max = max_value<int>();
469*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max)), "%c", max);
470*5c90c05cSAndroid Build Coastguard Worker // EXPECT_PRINTF("x", "%lc", L'x');
471*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(L"x", L"%c", L'x');
472*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format(L"{}", static_cast<wchar_t>(max)), L"%c", max);
473*5c90c05cSAndroid Build Coastguard Worker }
474*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,string)475*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, string) {
476*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("abc", "%s", "abc");
477*5c90c05cSAndroid Build Coastguard Worker const char* null_str = nullptr;
478*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("(null)", "%s", null_str);
479*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" (null)", "%10s", null_str);
480*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(L"abc", L"%s", L"abc");
481*5c90c05cSAndroid Build Coastguard Worker const wchar_t* null_wstr = nullptr;
482*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(L"(null)", L"%s", null_wstr);
483*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(L" (null)", L"%10s", null_wstr);
484*5c90c05cSAndroid Build Coastguard Worker }
485*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,pointer)486*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, pointer) {
487*5c90c05cSAndroid Build Coastguard Worker int n;
488*5c90c05cSAndroid Build Coastguard Worker void* p = &n;
489*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{}", p), "%p", p);
490*5c90c05cSAndroid Build Coastguard Worker p = nullptr;
491*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("(nil)", "%p", p);
492*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(" (nil)", "%10p", p);
493*5c90c05cSAndroid Build Coastguard Worker const char* s = "test";
494*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s);
495*5c90c05cSAndroid Build Coastguard Worker const char* null_str = nullptr;
496*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("(nil)", "%p", null_str);
497*5c90c05cSAndroid Build Coastguard Worker
498*5c90c05cSAndroid Build Coastguard Worker p = &n;
499*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format(L"{}", p), L"%p", p);
500*5c90c05cSAndroid Build Coastguard Worker p = nullptr;
501*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(L"(nil)", L"%p", p);
502*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(L" (nil)", L"%10p", p);
503*5c90c05cSAndroid Build Coastguard Worker const wchar_t* w = L"test";
504*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(fmt::format(L"{:p}", w), L"%p", w);
505*5c90c05cSAndroid Build Coastguard Worker const wchar_t* null_wstr = nullptr;
506*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF(L"(nil)", L"%p", null_wstr);
507*5c90c05cSAndroid Build Coastguard Worker }
508*5c90c05cSAndroid Build Coastguard Worker
509*5c90c05cSAndroid Build Coastguard Worker enum test_enum { answer = 42 };
format_as(test_enum e)510*5c90c05cSAndroid Build Coastguard Worker auto format_as(test_enum e) -> int { return e; }
511*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,enum)512*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, enum) {
513*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("42", "%d", answer);
514*5c90c05cSAndroid Build Coastguard Worker volatile test_enum volatile_enum = answer;
515*5c90c05cSAndroid Build Coastguard Worker EXPECT_PRINTF("42", "%d", volatile_enum);
516*5c90c05cSAndroid Build Coastguard Worker }
517*5c90c05cSAndroid Build Coastguard Worker
518*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_FCNTL
TEST(printf_test,examples)519*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, examples) {
520*5c90c05cSAndroid Build Coastguard Worker const char* weekday = "Thursday";
521*5c90c05cSAndroid Build Coastguard Worker const char* month = "August";
522*5c90c05cSAndroid Build Coastguard Worker int day = 21;
523*5c90c05cSAndroid Build Coastguard Worker EXPECT_WRITE(stdout, fmt::printf("%1$s, %3$d %2$s", weekday, month, day),
524*5c90c05cSAndroid Build Coastguard Worker "Thursday, 21 August");
525*5c90c05cSAndroid Build Coastguard Worker }
526*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,printf_error)527*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, printf_error) {
528*5c90c05cSAndroid Build Coastguard Worker auto pipe = fmt::pipe();
529*5c90c05cSAndroid Build Coastguard Worker int result = fmt::fprintf(pipe.read_end.fdopen("r").get(), "test");
530*5c90c05cSAndroid Build Coastguard Worker EXPECT_LT(result, 0);
531*5c90c05cSAndroid Build Coastguard Worker }
532*5c90c05cSAndroid Build Coastguard Worker #endif
533*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,wide_string)534*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, wide_string) {
535*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc"));
536*5c90c05cSAndroid Build Coastguard Worker }
537*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,vprintf)538*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, vprintf) {
539*5c90c05cSAndroid Build Coastguard Worker int n = 42;
540*5c90c05cSAndroid Build Coastguard Worker auto store = fmt::make_format_args<fmt::printf_context>(n);
541*5c90c05cSAndroid Build Coastguard Worker auto args = fmt::basic_format_args<fmt::printf_context>(store);
542*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(fmt::vsprintf(fmt::string_view("%d"), args), "42");
543*5c90c05cSAndroid Build Coastguard Worker EXPECT_WRITE(stdout, fmt::vfprintf(stdout, fmt::string_view("%d"), args),
544*5c90c05cSAndroid Build Coastguard Worker "42");
545*5c90c05cSAndroid Build Coastguard Worker }
546*5c90c05cSAndroid Build Coastguard Worker
547*5c90c05cSAndroid Build Coastguard Worker template <typename... Args>
check_format_string_regression(fmt::string_view s,const Args &...args)548*5c90c05cSAndroid Build Coastguard Worker void check_format_string_regression(fmt::string_view s, const Args&... args) {
549*5c90c05cSAndroid Build Coastguard Worker fmt::sprintf(s, args...);
550*5c90c05cSAndroid Build Coastguard Worker }
551*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,check_format_string_regression)552*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, check_format_string_regression) {
553*5c90c05cSAndroid Build Coastguard Worker check_format_string_regression("%c%s", 'x', "");
554*5c90c05cSAndroid Build Coastguard Worker }
555*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,fixed_large_exponent)556*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, fixed_large_exponent) {
557*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("1000000000000000000000", fmt::sprintf("%.*f", -13, 1e21));
558*5c90c05cSAndroid Build Coastguard Worker }
559*5c90c05cSAndroid Build Coastguard Worker
TEST(printf_test,make_printf_args)560*5c90c05cSAndroid Build Coastguard Worker TEST(printf_test, make_printf_args) {
561*5c90c05cSAndroid Build Coastguard Worker int n = 42;
562*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ("[42] something happened",
563*5c90c05cSAndroid Build Coastguard Worker fmt::vsprintf(fmt::string_view("[%d] %s happened"),
564*5c90c05cSAndroid Build Coastguard Worker {fmt::make_printf_args(n, "something")}));
565*5c90c05cSAndroid Build Coastguard Worker EXPECT_EQ(L"[42] something happened",
566*5c90c05cSAndroid Build Coastguard Worker fmt::vsprintf(fmt::basic_string_view<wchar_t>(L"[%d] %s happened"),
567*5c90c05cSAndroid Build Coastguard Worker {fmt::make_printf_args<wchar_t>(n, L"something")}));
568*5c90c05cSAndroid Build Coastguard Worker }
569