1 // Formatting library for C++ - printf tests
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
6 // For the license information refer to format.h.
13 #include "fmt/printf.h"
14 #include "gtest-extra.h"
18 using fmt::format_error
;
20 const unsigned BIG_NUM
= INT_MAX
+ 1u;
22 // Makes format string argument positional.
23 static std::string
make_positional(fmt::string_view format
) {
24 std::string
s(format
.data(), format
.size());
25 s
.replace(s
.find('%'), 1, "%1$");
29 static std::wstring
make_positional(fmt::wstring_view format
) {
30 std::wstring
s(format
.data(), format
.size());
31 s
.replace(s
.find(L
'%'), 1, L
"%1$");
35 // A wrapper around fmt::sprintf to workaround bogus warnings about invalid
36 // format strings in MSVC.
37 template <typename
... Args
>
38 std::string
test_sprintf(fmt::string_view format
, const Args
&... args
) {
39 return fmt::sprintf(format
, args
...);
41 template <typename
... Args
>
42 std::wstring
test_sprintf(fmt::wstring_view format
, const Args
&... args
) {
43 return fmt::sprintf(format
, args
...);
46 #define EXPECT_PRINTF(expected_output, format, arg) \
47 EXPECT_EQ(expected_output, test_sprintf(format, arg)) \
48 << "format: " << format; \
49 EXPECT_EQ(expected_output, fmt::sprintf(make_positional(format), arg))
51 TEST(PrintfTest
, NoArgs
) {
52 EXPECT_EQ("test", test_sprintf("test"));
53 EXPECT_EQ(L
"test", fmt::sprintf(L
"test"));
56 TEST(PrintfTest
, Escape
) {
57 EXPECT_EQ("%", test_sprintf("%%"));
58 EXPECT_EQ("before %", test_sprintf("before %%"));
59 EXPECT_EQ("% after", test_sprintf("%% after"));
60 EXPECT_EQ("before % after", test_sprintf("before %% after"));
61 EXPECT_EQ("%s", test_sprintf("%%s"));
62 EXPECT_EQ(L
"%", fmt::sprintf(L
"%%"));
63 EXPECT_EQ(L
"before %", fmt::sprintf(L
"before %%"));
64 EXPECT_EQ(L
"% after", fmt::sprintf(L
"%% after"));
65 EXPECT_EQ(L
"before % after", fmt::sprintf(L
"before %% after"));
66 EXPECT_EQ(L
"%s", fmt::sprintf(L
"%%s"));
69 TEST(PrintfTest
, PositionalArgs
) {
70 EXPECT_EQ("42", test_sprintf("%1$d", 42));
71 EXPECT_EQ("before 42", test_sprintf("before %1$d", 42));
72 EXPECT_EQ("42 after", test_sprintf("%1$d after",42));
73 EXPECT_EQ("before 42 after", test_sprintf("before %1$d after", 42));
74 EXPECT_EQ("answer = 42", test_sprintf("%1$s = %2$d", "answer", 42));
75 EXPECT_EQ("42 is the answer",
76 test_sprintf("%2$d is the %1$s", "answer", 42));
77 EXPECT_EQ("abracadabra", test_sprintf("%1$s%2$s%1$s", "abra", "cad"));
80 TEST(PrintfTest
, AutomaticArgIndexing
) {
81 EXPECT_EQ("abc", test_sprintf("%c%c%c", 'a', 'b', 'c'));
84 TEST(PrintfTest
, NumberIsTooBigInArgIndex
) {
85 EXPECT_THROW_MSG(test_sprintf(format("%{}$", BIG_NUM
)),
86 format_error
, "number is too big");
87 EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM
)),
88 format_error
, "number is too big");
91 TEST(PrintfTest
, SwitchArgIndexing
) {
92 EXPECT_THROW_MSG(test_sprintf("%1$d%", 1, 2),
93 format_error
, "cannot switch from manual to automatic argument indexing");
94 EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", BIG_NUM
), 1, 2),
95 format_error
, "number is too big");
96 EXPECT_THROW_MSG(test_sprintf("%1$d%d", 1, 2),
97 format_error
, "cannot switch from manual to automatic argument indexing");
99 EXPECT_THROW_MSG(test_sprintf("%d%1$", 1, 2),
100 format_error
, "cannot switch from automatic to manual argument indexing");
101 EXPECT_THROW_MSG(test_sprintf(format("%d%{}$d", BIG_NUM
), 1, 2),
102 format_error
, "number is too big");
103 EXPECT_THROW_MSG(test_sprintf("%d%1$d", 1, 2),
104 format_error
, "cannot switch from automatic to manual argument indexing");
106 // Indexing errors override width errors.
107 EXPECT_THROW_MSG(test_sprintf(format("%d%1${}d", BIG_NUM
), 1, 2),
108 format_error
, "number is too big");
109 EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", BIG_NUM
), 1, 2),
110 format_error
, "number is too big");
113 TEST(PrintfTest
, InvalidArgIndex
) {
114 EXPECT_THROW_MSG(test_sprintf("%0$d", 42), format_error
,
115 "argument index out of range");
116 EXPECT_THROW_MSG(test_sprintf("%2$d", 42), format_error
,
117 "argument index out of range");
118 EXPECT_THROW_MSG(test_sprintf(format("%{}$d", INT_MAX
), 42),
119 format_error
, "argument index out of range");
121 EXPECT_THROW_MSG(test_sprintf("%2$", 42),
122 format_error
, "argument index out of range");
123 EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM
), 42),
124 format_error
, "number is too big");
127 TEST(PrintfTest
, DefaultAlignRight
) {
128 EXPECT_PRINTF(" 42", "%5d", 42);
129 EXPECT_PRINTF(" abc", "%5s", "abc");
132 TEST(PrintfTest
, ZeroFlag
) {
133 EXPECT_PRINTF("00042", "%05d", 42);
134 EXPECT_PRINTF("-0042", "%05d", -42);
136 EXPECT_PRINTF("00042", "%05d", 42);
137 EXPECT_PRINTF("-0042", "%05d", -42);
138 EXPECT_PRINTF("-004.2", "%06g", -4.2);
140 EXPECT_PRINTF("+00042", "%00+6d", 42);
142 // '0' flag is ignored for non-numeric types.
143 EXPECT_PRINTF("0000x", "%05c", 'x');
146 TEST(PrintfTest
, PlusFlag
) {
147 EXPECT_PRINTF("+42", "%+d", 42);
148 EXPECT_PRINTF("-42", "%+d", -42);
149 EXPECT_PRINTF("+0042", "%+05d", 42);
150 EXPECT_PRINTF("+0042", "%0++5d", 42);
152 // '+' flag is ignored for non-numeric types.
153 EXPECT_PRINTF("x", "%+c", 'x');
156 TEST(PrintfTest
, MinusFlag
) {
157 EXPECT_PRINTF("abc ", "%-5s", "abc");
158 EXPECT_PRINTF("abc ", "%0--5s", "abc");
161 TEST(PrintfTest
, SpaceFlag
) {
162 EXPECT_PRINTF(" 42", "% d", 42);
163 EXPECT_PRINTF("-42", "% d", -42);
164 EXPECT_PRINTF(" 0042", "% 05d", 42);
165 EXPECT_PRINTF(" 0042", "%0 5d", 42);
167 // ' ' flag is ignored for non-numeric types.
168 EXPECT_PRINTF("x", "% c", 'x');
171 TEST(PrintfTest
, HashFlag
) {
172 EXPECT_PRINTF("042", "%#o", 042);
173 EXPECT_PRINTF(fmt::format("0{:o}", static_cast<unsigned>(-042)), "%#o", -042);
174 EXPECT_PRINTF("0", "%#o", 0);
176 EXPECT_PRINTF("0x42", "%#x", 0x42);
177 EXPECT_PRINTF("0X42", "%#X", 0x42);
179 fmt::format("0x{:x}", static_cast<unsigned>(-0x42)), "%#x", -0x42);
180 EXPECT_PRINTF("0", "%#x", 0);
182 EXPECT_PRINTF("0x0042", "%#06x", 0x42);
183 EXPECT_PRINTF("0x0042", "%0##6x", 0x42);
185 EXPECT_PRINTF("-42.000000", "%#f", -42.0);
186 EXPECT_PRINTF("-42.000000", "%#F", -42.0);
188 char buffer
[BUFFER_SIZE
];
189 safe_sprintf(buffer
, "%#e", -42.0);
190 EXPECT_PRINTF(buffer
, "%#e", -42.0);
191 safe_sprintf(buffer
, "%#E", -42.0);
192 EXPECT_PRINTF(buffer
, "%#E", -42.0);
194 EXPECT_PRINTF("-42.0000", "%#g", -42.0);
195 EXPECT_PRINTF("-42.0000", "%#G", -42.0);
197 safe_sprintf(buffer
, "%#a", 16.0);
198 EXPECT_PRINTF(buffer
, "%#a", 16.0);
199 safe_sprintf(buffer
, "%#A", 16.0);
200 EXPECT_PRINTF(buffer
, "%#A", 16.0);
202 // '#' flag is ignored for non-numeric types.
203 EXPECT_PRINTF("x", "%#c", 'x');
206 TEST(PrintfTest
, Width
) {
207 EXPECT_PRINTF(" abc", "%5s", "abc");
209 // Width cannot be specified twice.
210 EXPECT_THROW_MSG(test_sprintf("%5-5d", 42), format_error
,
211 "invalid type specifier");
213 EXPECT_THROW_MSG(test_sprintf(format("%{}d", BIG_NUM
), 42),
214 format_error
, "number is too big");
215 EXPECT_THROW_MSG(test_sprintf(format("%1${}d", BIG_NUM
), 42),
216 format_error
, "number is too big");
219 TEST(PrintfTest
, DynamicWidth
) {
220 EXPECT_EQ(" 42", test_sprintf("%*d", 5, 42));
221 EXPECT_EQ("42 ", test_sprintf("%*d", -5, 42));
222 EXPECT_THROW_MSG(test_sprintf("%*d", 5.0, 42), format_error
,
223 "width is not integer");
224 EXPECT_THROW_MSG(test_sprintf("%*d"), format_error
,
225 "argument index out of range");
226 EXPECT_THROW_MSG(test_sprintf("%*d", BIG_NUM
, 42), format_error
,
227 "number is too big");
230 TEST(PrintfTest
, IntPrecision
) {
231 EXPECT_PRINTF("00042", "%.5d", 42);
232 EXPECT_PRINTF("-00042", "%.5d", -42);
233 EXPECT_PRINTF("00042", "%.5x", 0x42);
234 EXPECT_PRINTF("0x00042", "%#.5x", 0x42);
235 EXPECT_PRINTF("00042", "%.5o", 042);
236 EXPECT_PRINTF("00042", "%#.5o", 042);
238 EXPECT_PRINTF(" 00042", "%7.5d", 42);
239 EXPECT_PRINTF(" 00042", "%7.5x", 0x42);
240 EXPECT_PRINTF(" 0x00042", "%#10.5x", 0x42);
241 EXPECT_PRINTF(" 00042", "%7.5o", 042);
242 EXPECT_PRINTF(" 00042", "%#10.5o", 042);
244 EXPECT_PRINTF("00042 ", "%-7.5d", 42);
245 EXPECT_PRINTF("00042 ", "%-7.5x", 0x42);
246 EXPECT_PRINTF("0x00042 ", "%-#10.5x", 0x42);
247 EXPECT_PRINTF("00042 ", "%-7.5o", 042);
248 EXPECT_PRINTF("00042 ", "%-#10.5o", 042);
251 TEST(PrintfTest
, FloatPrecision
) {
252 char buffer
[BUFFER_SIZE
];
253 safe_sprintf(buffer
, "%.3e", 1234.5678);
254 EXPECT_PRINTF(buffer
, "%.3e", 1234.5678);
255 EXPECT_PRINTF("1234.568", "%.3f", 1234.5678);
256 safe_sprintf(buffer
, "%.3g", 1234.5678);
257 EXPECT_PRINTF(buffer
, "%.3g", 1234.5678);
258 safe_sprintf(buffer
, "%.3a", 1234.5678);
259 EXPECT_PRINTF(buffer
, "%.3a", 1234.5678);
262 TEST(PrintfTest
, IgnorePrecisionForNonNumericArg
) {
263 EXPECT_PRINTF("abc", "%.5s", "abc");
266 TEST(PrintfTest
, DynamicPrecision
) {
267 EXPECT_EQ("00042", test_sprintf("%.*d", 5, 42));
268 EXPECT_EQ("42", test_sprintf("%.*d", -5, 42));
269 EXPECT_THROW_MSG(test_sprintf("%.*d", 5.0, 42), format_error
,
270 "precision is not integer");
271 EXPECT_THROW_MSG(test_sprintf("%.*d"), format_error
,
272 "argument index out of range");
273 EXPECT_THROW_MSG(test_sprintf("%.*d", BIG_NUM
, 42), format_error
,
274 "number is too big");
275 if (sizeof(long long) != sizeof(int)) {
276 long long prec
= static_cast<long long>(INT_MIN
) - 1;
277 EXPECT_THROW_MSG(test_sprintf("%.*d", prec
, 42), format_error
,
278 "number is too big");
282 template <typename T
>
283 struct make_signed
{ typedef T type
; };
285 #define SPECIALIZE_MAKE_SIGNED(T, S) \
287 struct make_signed<T> { typedef S type; }
289 SPECIALIZE_MAKE_SIGNED(char, signed char);
290 SPECIALIZE_MAKE_SIGNED(unsigned char, signed char);
291 SPECIALIZE_MAKE_SIGNED(unsigned short, short);
292 SPECIALIZE_MAKE_SIGNED(unsigned, int);
293 SPECIALIZE_MAKE_SIGNED(unsigned long, long);
294 SPECIALIZE_MAKE_SIGNED(unsigned long long, long long);
296 // Test length format specifier ``length_spec``.
297 template <typename T
, typename U
>
298 void TestLength(const char *length_spec
, U value
) {
299 long long signed_value
= 0;
300 unsigned long long unsigned_value
= 0;
301 // Apply integer promotion to the argument.
302 using std::numeric_limits
;
303 unsigned long long max
= numeric_limits
<U
>::max();
304 using fmt::internal::const_check
;
305 if (const_check(max
<= static_cast<unsigned>(numeric_limits
<int>::max()))) {
306 signed_value
= static_cast<int>(value
);
307 unsigned_value
= static_cast<unsigned>(value
);
308 } else if (const_check(max
<= numeric_limits
<unsigned>::max())) {
309 signed_value
= static_cast<unsigned>(value
);
310 unsigned_value
= static_cast<unsigned>(value
);
312 if (sizeof(U
) <= sizeof(int) && sizeof(int) < sizeof(T
)) {
313 signed_value
= static_cast<long long>(value
);
315 static_cast<typename
std::make_unsigned
<unsigned>::type
>(value
);
317 signed_value
= static_cast<typename make_signed
<T
>::type
>(value
);
318 unsigned_value
= static_cast<typename
std::make_unsigned
<T
>::type
>(value
);
320 std::ostringstream os
;
322 EXPECT_PRINTF(os
.str(), fmt::format("%{}d", length_spec
), value
);
323 EXPECT_PRINTF(os
.str(), fmt::format("%{}i", length_spec
), value
);
325 os
<< unsigned_value
;
326 EXPECT_PRINTF(os
.str(), fmt::format("%{}u", length_spec
), value
);
328 os
<< std::oct
<< unsigned_value
;
329 EXPECT_PRINTF(os
.str(), fmt::format("%{}o", length_spec
), value
);
331 os
<< std::hex
<< unsigned_value
;
332 EXPECT_PRINTF(os
.str(), fmt::format("%{}x", length_spec
), value
);
334 os
<< std::hex
<< std::uppercase
<< unsigned_value
;
335 EXPECT_PRINTF(os
.str(), fmt::format("%{}X", length_spec
), value
);
338 template <typename T
>
339 void TestLength(const char *length_spec
) {
340 T min
= std::numeric_limits
<T
>::min(), max
= std::numeric_limits
<T
>::max();
341 TestLength
<T
>(length_spec
, 42);
342 TestLength
<T
>(length_spec
, -42);
343 TestLength
<T
>(length_spec
, min
);
344 TestLength
<T
>(length_spec
, max
);
345 TestLength
<T
>(length_spec
, static_cast<long long>(min
) - 1);
346 unsigned long long long_long_max
= std::numeric_limits
<long long>::max();
347 if (static_cast<unsigned long long>(max
) < long_long_max
)
348 TestLength
<T
>(length_spec
, static_cast<long long>(max
) + 1);
349 TestLength
<T
>(length_spec
, std::numeric_limits
<short>::min());
350 TestLength
<T
>(length_spec
, std::numeric_limits
<unsigned short>::max());
351 TestLength
<T
>(length_spec
, std::numeric_limits
<int>::min());
352 TestLength
<T
>(length_spec
, std::numeric_limits
<int>::max());
353 TestLength
<T
>(length_spec
, std::numeric_limits
<unsigned>::min());
354 TestLength
<T
>(length_spec
, std::numeric_limits
<unsigned>::max());
355 TestLength
<T
>(length_spec
, std::numeric_limits
<long long>::min());
356 TestLength
<T
>(length_spec
, std::numeric_limits
<long long>::max());
357 TestLength
<T
>(length_spec
, std::numeric_limits
<unsigned long long>::min());
358 TestLength
<T
>(length_spec
, std::numeric_limits
<unsigned long long>::max());
361 TEST(PrintfTest
, Length
) {
362 TestLength
<char>("hh");
363 TestLength
<signed char>("hh");
364 TestLength
<unsigned char>("hh");
365 TestLength
<short>("h");
366 TestLength
<unsigned short>("h");
367 TestLength
<long>("l");
368 TestLength
<unsigned long>("l");
369 TestLength
<long long>("ll");
370 TestLength
<unsigned long long>("ll");
371 TestLength
<intmax_t>("j");
372 TestLength
<std::size_t>("z");
373 TestLength
<std::ptrdiff_t>("t");
374 long double max
= std::numeric_limits
<long double>::max();
375 EXPECT_PRINTF(fmt::format("{}", max
), "%g", max
);
376 EXPECT_PRINTF(fmt::format("{}", max
), "%Lg", max
);
379 TEST(PrintfTest
, Bool
) {
380 EXPECT_PRINTF("1", "%d", true);
381 EXPECT_PRINTF("true", "%s", true);
384 TEST(PrintfTest
, Int
) {
385 EXPECT_PRINTF("-42", "%d", -42);
386 EXPECT_PRINTF("-42", "%i", -42);
387 unsigned u
= 0 - 42u;
388 EXPECT_PRINTF(fmt::format("{}", u
), "%u", -42);
389 EXPECT_PRINTF(fmt::format("{:o}", u
), "%o", -42);
390 EXPECT_PRINTF(fmt::format("{:x}", u
), "%x", -42);
391 EXPECT_PRINTF(fmt::format("{:X}", u
), "%X", -42);
394 TEST(PrintfTest
, long_long
) {
395 // fmt::printf allows passing long long arguments to %d without length
397 long long max
= std::numeric_limits
<long long>::max();
398 EXPECT_PRINTF(fmt::format("{}", max
), "%d", max
);
401 TEST(PrintfTest
, Float
) {
402 EXPECT_PRINTF("392.650000", "%f", 392.65);
403 EXPECT_PRINTF("392.65", "%.2f", 392.65);
404 EXPECT_PRINTF("392.6", "%.1f", 392.65);
405 EXPECT_PRINTF("393", "%.f", 392.65);
406 EXPECT_PRINTF("392.650000", "%F", 392.65);
407 char buffer
[BUFFER_SIZE
];
408 safe_sprintf(buffer
, "%e", 392.65);
409 EXPECT_PRINTF(buffer
, "%e", 392.65);
410 safe_sprintf(buffer
, "%E", 392.65);
411 EXPECT_PRINTF(buffer
, "%E", 392.65);
412 EXPECT_PRINTF("392.65", "%g", 392.65);
413 EXPECT_PRINTF("392.65", "%G", 392.65);
414 safe_sprintf(buffer
, "%a", -392.65);
415 EXPECT_EQ(buffer
, format("{:a}", -392.65));
416 safe_sprintf(buffer
, "%A", -392.65);
417 EXPECT_EQ(buffer
, format("{:A}", -392.65));
420 TEST(PrintfTest
, Inf
) {
421 double inf
= std::numeric_limits
<double>::infinity();
422 for (const char* type
= "fega"; *type
; ++type
) {
423 EXPECT_PRINTF("inf", fmt::format("%{}", *type
), inf
);
424 char upper
= static_cast<char>(std::toupper(*type
));
425 EXPECT_PRINTF("INF", fmt::format("%{}", upper
), inf
);
429 TEST(PrintfTest
, Char
) {
430 EXPECT_PRINTF("x", "%c", 'x');
431 int max
= std::numeric_limits
<int>::max();
432 EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max
)), "%c", max
);
433 //EXPECT_PRINTF("x", "%lc", L'x');
434 EXPECT_PRINTF(L
"x", L
"%c", L
'x');
435 EXPECT_PRINTF(fmt::format(L
"{}", static_cast<wchar_t>(max
)), L
"%c", max
);
438 TEST(PrintfTest
, String
) {
439 EXPECT_PRINTF("abc", "%s", "abc");
440 const char *null_str
= FMT_NULL
;
441 EXPECT_PRINTF("(null)", "%s", null_str
);
442 EXPECT_PRINTF(" (null)", "%10s", null_str
);
443 EXPECT_PRINTF(L
"abc", L
"%s", L
"abc");
444 const wchar_t *null_wstr
= FMT_NULL
;
445 EXPECT_PRINTF(L
"(null)", L
"%s", null_wstr
);
446 EXPECT_PRINTF(L
" (null)", L
"%10s", null_wstr
);
449 TEST(PrintfTest
, Pointer
) {
452 EXPECT_PRINTF(fmt::format("{}", p
), "%p", p
);
454 EXPECT_PRINTF("(nil)", "%p", p
);
455 EXPECT_PRINTF(" (nil)", "%10p", p
);
456 const char *s
= "test";
457 EXPECT_PRINTF(fmt::format("{:p}", s
), "%p", s
);
458 const char *null_str
= FMT_NULL
;
459 EXPECT_PRINTF("(nil)", "%p", null_str
);
462 EXPECT_PRINTF(fmt::format(L
"{}", p
), L
"%p", p
);
464 EXPECT_PRINTF(L
"(nil)", L
"%p", p
);
465 EXPECT_PRINTF(L
" (nil)", L
"%10p", p
);
466 const wchar_t *w
= L
"test";
467 EXPECT_PRINTF(fmt::format(L
"{:p}", w
), L
"%p", w
);
468 const wchar_t *null_wstr
= FMT_NULL
;
469 EXPECT_PRINTF(L
"(nil)", L
"%p", null_wstr
);
472 TEST(PrintfTest
, Location
) {
478 TEST(PrintfTest
, Enum
) {
479 EXPECT_PRINTF("42", "%d", A
);
482 #if FMT_USE_FILE_DESCRIPTORS
483 TEST(PrintfTest
, Examples
) {
484 const char *weekday
= "Thursday";
485 const char *month
= "August";
487 EXPECT_WRITE(stdout
, fmt::printf("%1$s, %3$d %2$s", weekday
, month
, day
),
488 "Thursday, 21 August");
491 TEST(PrintfTest
, PrintfError
) {
492 fmt::file read_end
, write_end
;
493 fmt::file::pipe(read_end
, write_end
);
494 int result
= fmt::fprintf(read_end
.fdopen("r").get(), "test");
495 EXPECT_LT(result
, 0);
499 TEST(PrintfTest
, WideString
) {
500 EXPECT_EQ(L
"abc", fmt::sprintf(L
"%s", L
"abc"));
503 TEST(PrintfTest
, PrintfCustom
) {
504 EXPECT_EQ("abc", test_sprintf("%s", TestString("abc")));
507 TEST(PrintfTest
, OStream
) {
508 std::ostringstream os
;
509 int ret
= fmt::fprintf(os
, "Don't %s!", "panic");
510 EXPECT_EQ("Don't panic!", os
.str());
514 TEST(PrintfTest
, VPrintf
) {
515 fmt::format_arg_store
<fmt::printf_context
, int> as
{42};
516 fmt::basic_format_args
<fmt::printf_context
> args(as
);
517 EXPECT_EQ(fmt::vsprintf("%d", args
), "42");
518 EXPECT_WRITE(stdout
, fmt::vprintf("%d", args
), "42");
519 EXPECT_WRITE(stdout
, fmt::vfprintf(stdout
, "%d", args
), "42");
520 EXPECT_WRITE(stdout
, fmt::vfprintf(std::cout
, "%d", args
), "42");
523 template<typename
... Args
>
524 void check_format_string_regression(fmt::string_view s
, const Args
&... args
) {
525 fmt::sprintf(s
, args
...);
528 TEST(PrintfTest
, CheckFormatStringRegression
) {
529 check_format_string_regression("%c%s", 'x', "");
532 TEST(PrintfTest
, VSPrintfMakeArgsExample
) {
533 fmt::format_arg_store
<fmt::printf_context
, int, const char *> as
{
535 fmt::basic_format_args
<fmt::printf_context
> args(as
);
537 "[42] something happened", fmt::vsprintf("[%d] %s happened", args
));
538 auto as2
= fmt::make_printf_args(42, "something");
539 fmt::basic_format_args
<fmt::printf_context
> args2(as2
);
541 "[42] something happened", fmt::vsprintf("[%d] %s happened", args2
));
542 //the older gcc versions can't cast the return value
543 #if !defined(__GNUC__) || (__GNUC__ > 4)
545 "[42] something happened",
547 "[%d] %s happened", fmt::make_printf_args(42, "something")));
551 TEST(PrintfTest
, VSPrintfMakeWArgsExample
) {
552 fmt::format_arg_store
<fmt::wprintf_context
, int, const wchar_t *> as
{
554 fmt::basic_format_args
<fmt::wprintf_context
> args(as
);
556 L
"[42] something happened",
557 fmt::vsprintf(L
"[%d] %s happened", args
));
558 auto as2
= fmt::make_wprintf_args(42, L
"something");
559 fmt::basic_format_args
<fmt::wprintf_context
> args2(as2
);
561 L
"[42] something happened", fmt::vsprintf(L
"[%d] %s happened", args2
));
562 // the older gcc versions can't cast the return value
563 #if !defined(__GNUC__) || (__GNUC__ > 4)
565 L
"[42] something happened",
567 L
"[%d] %s happened", fmt::make_wprintf_args(42, L
"something")));