brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · fe49876 Raw
157 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: libcpp-has-no-unicode12// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME13 14// TODO PRINT Enable again15// https://reviews.llvm.org/D15004416// https://lab.llvm.org/buildbot/#/builders/237/builds/357817// UNSUPPORTED: asan, hwasan, msan18 19// XFAIL: availability-fp_to_chars-missing20 21// The error exception has no system error string.22// XFAIL: LIBCXX-ANDROID-FIXME23 24// <print>25 26// void vprint_unicode(FILE* stream, string_view fmt, format_args args);27 28// In the library when the stdout is redirected to a file it is no29// longer considered a terminal and the special terminal handling is no30// longer executed. There are tests in31//   libcxx/test/libcxx/input.output/iostream.format/print.fun/32// to validate that behaviour33 34#include <algorithm>35#include <array>36#include <cassert>37#include <cstddef>38#include <cstdio>39#include <fstream>40#include <iterator>41#include <print>42#include <string_view>43 44#include "assert_macros.h"45#include "concat_macros.h"46#include "filesystem_test_helper.h"47#include "print_tests.h"48#include "test_macros.h"49 50scoped_test_env env;51std::string filename = env.create_file("output.txt");52 53auto test_file = []<class... Args>(std::string_view expected, std::string_view fmt, Args&&... args) {54  FILE* file = fopen(filename.c_str(), "wb");55  assert(file);56 57  std::vprint_unicode(file, fmt, std::make_format_args(args...));58  std::fclose(file);59 60  std::ifstream stream{filename.c_str(), std::ios_base::in | std::ios_base::binary};61  std::string out(std::istreambuf_iterator<char>{stream}, {});62  TEST_REQUIRE(out == expected,63               TEST_WRITE_CONCATENATED(64                   "\nFormat string   ", fmt, "\nExpected output ", expected, "\nActual output   ", out, '\n'));65};66 67auto test_exception = []<class... Args>([[maybe_unused]] std::string_view what,68                                        [[maybe_unused]] std::string_view fmt,69                                        [[maybe_unused]] Args&&... args) {70  FILE* file = fopen(filename.c_str(), "wb");71  assert(file);72 73  TEST_VALIDATE_EXCEPTION(74      std::format_error,75      [&]([[maybe_unused]] const std::format_error& e) {76        TEST_LIBCPP_REQUIRE(77            e.what() == what,78            TEST_WRITE_CONCATENATED(79                "\nFormat string   ", fmt, "\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));80      },81      std::vprint_unicode(file, fmt, std::make_format_args(args...)));82 83  fclose(file);84};85 86// Glibc fails writing to a wide stream.87#if defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)88static void test_wide_stream() {89  FILE* file = fopen(filename.c_str(), "wb");90  assert(file);91 92  int mode = std::fwide(file, 1);93  assert(mode > 0);94 95  TEST_VALIDATE_EXCEPTION(96      std::system_error,97      [&]([[maybe_unused]] const std::system_error& e) {98        [[maybe_unused]] std::string_view what{"failed to write formatted output"};99        TEST_LIBCPP_REQUIRE(100            e.what() == what,101            TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));102      },103      std::vprint_unicode(file, "hello", std::make_format_args()));104}105#endif // defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)106 107static void test_read_only() {108  FILE* file = fopen(filename.c_str(), "r");109  assert(file);110 111  TEST_VALIDATE_EXCEPTION(112      std::system_error,113      [&]([[maybe_unused]] const std::system_error& e) {114        [[maybe_unused]] std::string_view what{115            "failed to write formatted output: " TEST_IF_AIX("Broken pipe", "Operation not permitted")};116        TEST_LIBCPP_REQUIRE(117            e.what() == what,118            TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));119      },120      std::vprint_unicode(file, "hello", std::make_format_args()));121}122 123static void test_new_line() {124  // Text does newline translation.125  {126    FILE* file = fopen(filename.c_str(), "w");127    assert(file);128 129    std::vprint_unicode(file, "\n", std::make_format_args());130#ifndef _WIN32131    assert(std::ftell(file) == 1);132#else133    assert(std::ftell(file) == 2);134#endif135  }136  // Binary no newline translation.137  {138    FILE* file = fopen(filename.c_str(), "wb");139    assert(file);140 141    std::vprint_unicode(file, "\n", std::make_format_args());142    assert(std::ftell(file) == 1);143  }144}145 146int main(int, char**) {147  print_tests(test_file, test_exception);148 149#if defined(TEST_HAS_GLIBC) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)150  test_wide_stream();151#endif152  test_read_only();153  test_new_line();154 155  return 0;156}157