brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · fc40680 Raw
168 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010// UNSUPPORTED: no-filesystem11// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME12 13// XFAIL: availability-fp_to_chars-missing14 15// The error exception has no system error string.16// XFAIL: LIBCXX-ANDROID-FIXME17 18// <print>19 20// template<class... Args>21//   void println(FILE* stream, format_string<Args...> fmt, Args&&... args);22 23// In the library when the stdout is redirected to a file it is no24// longer considered a terminal and the special terminal handling is no25// longer executed. There are tests in26//   libcxx/test/libcxx/input.output/iostream.format/print.fun/27// to validate that behaviour28 29#include <algorithm>30#include <array>31#include <cassert>32#include <cstddef>33#include <cstdio>34#include <fstream>35#include <fstream>36#include <iterator>37#include <print>38#include <string_view>39 40#include "assert_macros.h"41#include "concat_macros.h"42#include "filesystem_test_helper.h"43#include "print_tests.h"44#include "test_format_string.h"45#include "test_macros.h"46 47scoped_test_env env;48std::string filename = env.create_file("output.txt");49 50auto test_file = []<class... Args>(std::string_view e, test_format_string<char, Args...> fmt, Args&&... args) {51  std::string expected = std::string{e} + '\n';52 53  FILE* file = fopen(filename.c_str(), "wb");54  assert(file);55 56  std::println(file, fmt, std::forward<Args>(args)...);57  std::fclose(file);58 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.get(), "\nExpected output ", expected, "\nActual output   ", out, '\n'));64};65 66auto test_exception = []<class... Args>(std::string_view, std::string_view, Args&&...) {67  // After P2216 most exceptions thrown by std::format become ill-formed.68  // Therefore this tests does nothing.69  // A basic ill-formed test is done in format.verify.cpp70  // The exceptions are tested by other functions that don't use the basic-format-string as fmt argument.71};72 73// Glibc fails writing to a wide stream.74#if defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)75static void test_wide_stream() {76  FILE* file = fopen(filename.c_str(), "wb");77  assert(file);78 79  int mode = std::fwide(file, 1);80  assert(mode > 0);81 82  TEST_VALIDATE_EXCEPTION(83      std::system_error,84      [&]([[maybe_unused]] const std::system_error& e) {85        [[maybe_unused]] std::string_view what{"failed to write formatted output"};86        TEST_LIBCPP_REQUIRE(87            e.what() == what,88            TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));89      },90      std::println(file, "hello"));91}92#endif // defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)93 94static void test_read_only() {95  FILE* file = fopen(filename.c_str(), "r");96  assert(file);97 98  TEST_VALIDATE_EXCEPTION(99      std::system_error,100      [&]([[maybe_unused]] const std::system_error& e) {101        [[maybe_unused]] std::string_view what{102            "failed to write formatted output: " TEST_IF_AIX("Broken pipe", "Operation not permitted")};103        TEST_LIBCPP_REQUIRE(104            e.what() == what,105            TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));106      },107      std::println(file, "hello"));108}109 110static void test_new_line() {111  // Text does newline translation.112  {113    FILE* file = fopen(filename.c_str(), "w");114    assert(file);115 116    std::println(file, "");117#ifndef _WIN32118    assert(std::ftell(file) == 1);119#else120    assert(std::ftell(file) == 2);121#endif122  }123  // Binary no newline translation.124  {125    FILE* file = fopen(filename.c_str(), "wb");126    assert(file);127 128    std::println(file, "");129    assert(std::ftell(file) == 1);130  }131}132 133static void test_println_blank_line() {134  // Text does newline translation.135  {136    FILE* file = fopen(filename.c_str(), "w");137    assert(file);138 139    std::println(file);140#ifndef _WIN32141    assert(std::ftell(file) == 1);142#else143    assert(std::ftell(file) == 2);144#endif145  }146  // Binary no newline translation.147  {148    FILE* file = fopen(filename.c_str(), "wb");149    assert(file);150 151    std::println(file);152    assert(std::ftell(file) == 1);153  }154}155 156int main(int, char**) {157  print_tests(test_file, test_exception);158 159#if defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)160  test_wide_stream();161#endif162  test_read_only();163  test_new_line();164  test_println_blank_line();165 166  return 0;167}168