151af4fddSLouis Dionne //===----------------------------------------------------------------------===// 26a54dfbfSLouis Dionne // 351af4fddSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 451af4fddSLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 551af4fddSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 651af4fddSLouis Dionne // 751af4fddSLouis Dionne //===----------------------------------------------------------------------===// 851af4fddSLouis Dionne 9*de5ff8adSMark de Wever // REQUIRES: std-at-least-c++23 101cf970dbSKonstantin Varlamov // UNSUPPORTED: no-filesystem 113f65f718SMark de Wever // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME 123f65f718SMark de Wever 133f65f718SMark de Wever // XFAIL: msvc, target={{.+}}-windows-gnu 143f65f718SMark de Wever // XFAIL: availability-fp_to_chars-missing 153f65f718SMark de Wever 16bce3b505SRyan Prichard // fmemopen is available starting in Android M (API 23) 17bce3b505SRyan Prichard // XFAIL: target={{.+}}-android{{(eabi)?(21|22)}} 18bce3b505SRyan Prichard 193f65f718SMark de Wever // <print> 203f65f718SMark de Wever 213f65f718SMark de Wever // The FILE returned by fmemopen does not have file descriptor. 223f65f718SMark de Wever // This means the test could fail when the implementation uses a 233f65f718SMark de Wever // function that requires a file descriptor, for example write. 243f65f718SMark de Wever // 253f65f718SMark de Wever // This tests all print functions which takes a FILE* as argument. 263f65f718SMark de Wever 273f65f718SMark de Wever // template<class... Args> 283f65f718SMark de Wever // void print(FILE* stream, format_string<Args...> fmt, Args&&... args); 297f9f82e3SHristo Hristov // void println(); // Since C++26 303f65f718SMark de Wever // template<class... Args> 313f65f718SMark de Wever // void println(FILE* stream, format_string<Args...> fmt, Args&&... args); 327f9f82e3SHristo Hristov // void println(FILE* stream); // Since C++26 333f65f718SMark de Wever // void vprint_unicode(FILE* stream, string_view fmt, format_args args); 343f65f718SMark de Wever // void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); 353f65f718SMark de Wever 363f65f718SMark de Wever #include <array> 373f65f718SMark de Wever #include <cstdio> 383f65f718SMark de Wever #include <cassert> 393f65f718SMark de Wever #include <print> 403f65f718SMark de Wever 413f65f718SMark de Wever static void test_print() { 423f65f718SMark de Wever std::array<char, 100> buffer{0}; 433f65f718SMark de Wever 443f65f718SMark de Wever FILE* file = fmemopen(buffer.data(), buffer.size(), "wb"); 453f65f718SMark de Wever assert(file); 463f65f718SMark de Wever 473f65f718SMark de Wever std::print(file, "hello world{}", '!'); 483f65f718SMark de Wever long pos = std::ftell(file); 493f65f718SMark de Wever std::fclose(file); 503f65f718SMark de Wever 513f65f718SMark de Wever assert(pos > 0); 523f65f718SMark de Wever assert(std::string_view(buffer.data(), pos) == "hello world!"); 533f65f718SMark de Wever } 543f65f718SMark de Wever 553f65f718SMark de Wever static void test_println() { 563f65f718SMark de Wever std::array<char, 100> buffer{0}; 573f65f718SMark de Wever 583f65f718SMark de Wever FILE* file = fmemopen(buffer.data(), buffer.size(), "wb"); 593f65f718SMark de Wever assert(file); 603f65f718SMark de Wever 613f65f718SMark de Wever std::println(file, "hello world{}", '!'); 623f65f718SMark de Wever long pos = std::ftell(file); 633f65f718SMark de Wever std::fclose(file); 643f65f718SMark de Wever 653f65f718SMark de Wever assert(pos > 0); 663f65f718SMark de Wever assert(std::string_view(buffer.data(), pos) == "hello world!\n"); 673f65f718SMark de Wever } 683f65f718SMark de Wever 697f9f82e3SHristo Hristov static void test_println_blank_line() { 707f9f82e3SHristo Hristov std::array<char, 100> buffer{0}; 717f9f82e3SHristo Hristov 727f9f82e3SHristo Hristov FILE* file = fmemopen(buffer.data(), buffer.size(), "wb"); 737f9f82e3SHristo Hristov assert(file); 747f9f82e3SHristo Hristov 757f9f82e3SHristo Hristov std::println(file); 767f9f82e3SHristo Hristov long pos = std::ftell(file); 777f9f82e3SHristo Hristov std::fclose(file); 787f9f82e3SHristo Hristov 797f9f82e3SHristo Hristov assert(pos > 0); 807f9f82e3SHristo Hristov assert(std::string_view(buffer.data(), pos) == "\n"); 817f9f82e3SHristo Hristov } 827f9f82e3SHristo Hristov 833f65f718SMark de Wever static void test_vprint_unicode() { 8404a75f54SLouis Dionne #ifdef TEST_HAS_NO_UNICODE 853f65f718SMark de Wever std::array<char, 100> buffer{0}; 863f65f718SMark de Wever 873f65f718SMark de Wever FILE* file = fmemopen(buffer.data(), buffer.size(), "wb"); 883f65f718SMark de Wever assert(file); 893f65f718SMark de Wever 90e3f154d8SMark de Wever char c = '!'; 91e3f154d8SMark de Wever std::vprint_unicode(file, "hello world{}", std::make_format_args(c)); 923f65f718SMark de Wever long pos = std::ftell(file); 933f65f718SMark de Wever std::fclose(file); 943f65f718SMark de Wever 953f65f718SMark de Wever assert(pos > 0); 963f65f718SMark de Wever assert(std::string_view(buffer.data(), pos) == "hello world!"); 9704a75f54SLouis Dionne #endif // TEST_HAS_NO_UNICODE 983f65f718SMark de Wever } 993f65f718SMark de Wever 1003f65f718SMark de Wever static void test_vprint_nonunicode() { 1013f65f718SMark de Wever std::array<char, 100> buffer{0}; 1023f65f718SMark de Wever 1033f65f718SMark de Wever FILE* file = fmemopen(buffer.data(), buffer.size(), "wb"); 1043f65f718SMark de Wever assert(file); 1053f65f718SMark de Wever 106e3f154d8SMark de Wever char c = '!'; 107e3f154d8SMark de Wever std::vprint_nonunicode(file, "hello world{}", std::make_format_args(c)); 1083f65f718SMark de Wever long pos = std::ftell(file); 1093f65f718SMark de Wever std::fclose(file); 1103f65f718SMark de Wever 1113f65f718SMark de Wever assert(pos > 0); 1123f65f718SMark de Wever assert(std::string_view(buffer.data(), pos) == "hello world!"); 1133f65f718SMark de Wever } 1143f65f718SMark de Wever 1153f65f718SMark de Wever int main(int, char**) { 1163f65f718SMark de Wever test_print(); 1173f65f718SMark de Wever test_println(); 1187f9f82e3SHristo Hristov test_println_blank_line(); 1193f65f718SMark de Wever test_vprint_unicode(); 1203f65f718SMark de Wever test_vprint_nonunicode(); 1213f65f718SMark de Wever 1223f65f718SMark de Wever return 0; 1233f65f718SMark de Wever } 124