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