1 //===----------------------------------------------------------------------===//
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //===----------------------------------------------------------------------===//
8 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9 // UNSUPPORTED: no-filesystem
10 // UNSUPPORTED: libcpp-has-no-unicode
11 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
13 // TODO PRINT Enable again
14 // https://reviews.llvm.org/D150044
15 // https://lab.llvm.org/buildbot/#/builders/237/builds/3578
16 // UNSUPPORTED: asan, hwasan, msan
18 // XFAIL: availability-fp_to_chars-missing
20 // The error exception has no system error string.
21 // XFAIL: LIBCXX-ANDROID-FIXME
25 // void vprint_unicode(FILE* stream, string_view fmt, format_args args);
27 // In the library when the stdout is redirected to a file it is no
28 // longer considered a terminal and the special terminal handling is no
29 // longer executed. There are tests in
30 // libcxx/test/libcxx/input.output/iostream.format/print.fun/
31 // to validate that behaviour
41 #include <string_view>
43 #include "assert_macros.h"
44 #include "concat_macros.h"
45 #include "filesystem_test_helper.h"
46 #include "print_tests.h"
47 #include "test_macros.h"
50 std::string filename
= env
.create_file("output.txt");
52 auto test_file
= []<class... Args
>(std::string_view expected
, std::string_view fmt
, Args
&&... args
) {
53 FILE* file
= fopen(filename
.c_str(), "wb");
56 std::vprint_unicode(file
, fmt
, std::make_format_args(args
...));
59 std::ifstream stream
{filename
.c_str(), std::ios_base::in
| std::ios_base::binary
};
60 std::string
out(std::istreambuf_iterator
<char>{stream
}, {});
61 TEST_REQUIRE(out
== expected
,
62 TEST_WRITE_CONCATENATED(
63 "\nFormat string ", fmt
, "\nExpected output ", expected
, "\nActual output ", out
, '\n'));
66 auto test_exception
= []<class... Args
>([[maybe_unused
]] std::string_view what
,
67 [[maybe_unused
]] std::string_view fmt
,
68 [[maybe_unused
]] Args
&&... args
) {
69 FILE* file
= fopen(filename
.c_str(), "wb");
72 TEST_VALIDATE_EXCEPTION(
74 [&]([[maybe_unused
]] const std::format_error
& e
) {
77 TEST_WRITE_CONCATENATED(
78 "\nFormat string ", fmt
, "\nExpected exception ", what
, "\nActual exception ", e
.what(), '\n'));
80 std::vprint_unicode(file
, fmt
, std::make_format_args(args
...)));
85 // Glibc fails writing to a wide stream.
86 #if defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)
87 static void test_wide_stream() {
88 FILE* file
= fopen(filename
.c_str(), "wb");
91 int mode
= std::fwide(file
, 1);
94 TEST_VALIDATE_EXCEPTION(
96 [&]([[maybe_unused
]] const std::system_error
& e
) {
97 [[maybe_unused
]] std::string_view what
{"failed to write formatted output"};
100 TEST_WRITE_CONCATENATED("\nExpected exception ", what
, "\nActual exception ", e
.what(), '\n'));
102 std::vprint_unicode(file
, "hello", std::make_format_args()));
104 #endif // defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)
106 static void test_read_only() {
107 FILE* file
= fopen(filename
.c_str(), "r");
110 TEST_VALIDATE_EXCEPTION(
112 [&]([[maybe_unused
]] const std::system_error
& e
) {
114 [[maybe_unused
]] std::string_view what
{"failed to write formatted output: Broken pipe"};
116 [[maybe_unused
]] std::string_view what
{"failed to write formatted output: Operation not permitted"};
120 TEST_WRITE_CONCATENATED("\nExpected exception ", what
, "\nActual exception ", e
.what(), '\n'));
122 std::vprint_unicode(file
, "hello", std::make_format_args()));
125 static void test_new_line() {
126 // Text does newline translation.
128 FILE* file
= fopen(filename
.c_str(), "w");
131 std::vprint_unicode(file
, "\n", std::make_format_args());
133 assert(std::ftell(file
) == 1);
135 assert(std::ftell(file
) == 2);
138 // Binary no newline translation.
140 FILE* file
= fopen(filename
.c_str(), "wb");
143 std::vprint_unicode(file
, "\n", std::make_format_args());
144 assert(std::ftell(file
) == 1);
148 int main(int, char**) {
149 print_tests(test_file
, test_exception
);
151 #if defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)