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
14// XFAIL: target={{.+}}-windows-gnu
15// XFAIL: availability-fp_to_chars-missing
16
17// fmemopen is available starting in Android M (API 23)
18// XFAIL: target={{.+}}-android{{(eabi)?(21|22)}}
19
20// <print>
21
22// The FILE returned by fmemopen does not have file descriptor.
23// This means the test could fail when the implementation uses a
24// function that requires a file descriptor, for example write.
25//
26// This tests all print functions which takes a FILE* as argument.
27
28// template<class... Args>
29// void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
30// void println(); // Since C++26
31// template<class... Args>
32// void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
33// void println(FILE* stream); // Since C++26
34// void vprint_unicode(FILE* stream, string_view fmt, format_args args);
35// void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
36
37#include <array>
38#include <cstdio>
39#include <cassert>
40#include <print>
41
42static void test_print() {
43 std::array<char, 100> buffer{0};
44
45 FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
46 assert(file);
47
48 std::print(file, "hello world{}", '!');
49 long pos = std::ftell(stream: file);
50 std::fclose(stream: file);
51
52 assert(pos > 0);
53 assert(std::string_view(buffer.data(), pos) == "hello world!");
54}
55
56static void test_println() {
57 std::array<char, 100> buffer{0};
58
59 FILE* file = fmemopen(s: buffer.data(), len: buffer.size(), modes: "wb");
60 assert(file);
61
62 std::println(stream: file, format: "hello world{}", '!');
63 long pos = std::ftell(stream: file);
64 std::fclose(stream: file);
65
66 assert(pos > 0);
67 assert(std::string_view(buffer.data(), pos) == "hello world!\n");
68}
69
70static void test_println_blank_line() {
71 std::array<char, 100> buffer{0};
72
73 FILE* file = fmemopen(s: buffer.data(), len: buffer.size(), modes: "wb");
74 assert(file);
75
76 std::println(file);
77 long pos = std::ftell(stream: file);
78 std::fclose(stream: file);
79
80 assert(pos > 0);
81 assert(std::string_view(buffer.data(), pos) == "\n");
82}
83
84static void test_vprint_unicode() {
85#ifdef TEST_HAS_NO_UNICODE
86 std::array<char, 100> buffer{0};
87
88 FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
89 assert(file);
90
91 char c = '!';
92 std::vprint_unicode(file, "hello world{}", std::make_format_args(c));
93 long pos = std::ftell(file);
94 std::fclose(file);
95
96 assert(pos > 0);
97 assert(std::string_view(buffer.data(), pos) == "hello world!");
98#endif // TEST_HAS_NO_UNICODE
99}
100
101static void test_vprint_nonunicode() {
102 std::array<char, 100> buffer{0};
103
104 FILE* file = fmemopen(s: buffer.data(), len: buffer.size(), modes: "wb");
105 assert(file);
106
107 char c = '!';
108 std::vprint_nonunicode(file, "hello world{}", std::make_format_args(c));
109 long pos = std::ftell(stream: file);
110 std::fclose(stream: file);
111
112 assert(pos > 0);
113 assert(std::string_view(buffer.data(), pos) == "hello world!");
114}
115
116int main(int, char**) {
117 test_print();
118 test_println();
119 test_println_blank_line();
120 test_vprint_unicode();
121 test_vprint_nonunicode();
122
123 return 0;
124}
125

source code of libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp