xref: /llvm-project/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp (revision de5ff8ad07ae824b86c5cefcba63f4b66607b759)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // REQUIRES: std-at-least-c++23
10 // UNSUPPORTED: no-filesystem
11 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12 
13 // XFAIL: msvc, target={{.+}}-windows-gnu
14 // XFAIL: availability-fp_to_chars-missing
15 
16 // fmemopen is available starting in Android M (API 23)
17 // XFAIL: target={{.+}}-android{{(eabi)?(21|22)}}
18 
19 // <print>
20 
21 // The FILE returned by fmemopen does not have file descriptor.
22 // This means the test could fail when the implementation uses a
23 // function that requires a file descriptor, for example write.
24 //
25 // This tests all print functions which takes a FILE* as argument.
26 
27 // template<class... Args>
28 //   void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
29 // void println();                                                          // Since C++26
30 // template<class... Args>
31 //   void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
32 // void println(FILE* stream);                                              // Since C++26
33 // void vprint_unicode(FILE* stream, string_view fmt, format_args args);
34 // void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
35 
36 #include <array>
37 #include <cstdio>
38 #include <cassert>
39 #include <print>
40 
41 static void test_print() {
42   std::array<char, 100> buffer{0};
43 
44   FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
45   assert(file);
46 
47   std::print(file, "hello world{}", '!');
48   long pos = std::ftell(file);
49   std::fclose(file);
50 
51   assert(pos > 0);
52   assert(std::string_view(buffer.data(), pos) == "hello world!");
53 }
54 
55 static void test_println() {
56   std::array<char, 100> buffer{0};
57 
58   FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
59   assert(file);
60 
61   std::println(file, "hello world{}", '!');
62   long pos = std::ftell(file);
63   std::fclose(file);
64 
65   assert(pos > 0);
66   assert(std::string_view(buffer.data(), pos) == "hello world!\n");
67 }
68 
69 static void test_println_blank_line() {
70   std::array<char, 100> buffer{0};
71 
72   FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
73   assert(file);
74 
75   std::println(file);
76   long pos = std::ftell(file);
77   std::fclose(file);
78 
79   assert(pos > 0);
80   assert(std::string_view(buffer.data(), pos) == "\n");
81 }
82 
83 static void test_vprint_unicode() {
84 #ifdef TEST_HAS_NO_UNICODE
85   std::array<char, 100> buffer{0};
86 
87   FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
88   assert(file);
89 
90   char c = '!';
91   std::vprint_unicode(file, "hello world{}", std::make_format_args(c));
92   long pos = std::ftell(file);
93   std::fclose(file);
94 
95   assert(pos > 0);
96   assert(std::string_view(buffer.data(), pos) == "hello world!");
97 #endif // TEST_HAS_NO_UNICODE
98 }
99 
100 static void test_vprint_nonunicode() {
101   std::array<char, 100> buffer{0};
102 
103   FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
104   assert(file);
105 
106   char c = '!';
107   std::vprint_nonunicode(file, "hello world{}", std::make_format_args(c));
108   long pos = std::ftell(file);
109   std::fclose(file);
110 
111   assert(pos > 0);
112   assert(std::string_view(buffer.data(), pos) == "hello world!");
113 }
114 
115 int main(int, char**) {
116   test_print();
117   test_println();
118   test_println_blank_line();
119   test_vprint_unicode();
120   test_vprint_nonunicode();
121 
122   return 0;
123 }
124