Files
clang-p2996/libcxx/test/std/input.output/file.streams/fstreams/filebuf.virtuals/setbuf.pass.cpp
Louis Dionne 0547e573c5 [runtimes] Run backdeployment CI on Github hosted runners (#109984)
This removes the need for macOS nodes in Buildkite. It also moves to the
proper way of testing backdeployment, which is to actually run on the
target OS itself, instead of using packaged dylibs from previous OS
versions and trying to emulate backdeployment with DYLD_LIBRARY_PATH.

As a drive-by change, also fix a few back-deployment annotations that
were incorrect and add support for minor versions in the Lit feature
determining availability from the target triple.
2024-09-30 17:08:44 -04:00

124 lines
3.1 KiB
C++

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// <fstream>
// basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n) override;
// In C++23 and later, this test requires support for P2467R1 in the dylib (a3f17ba3febbd546f2342ffc780ac93b694fdc8d)
// XFAIL: (!c++03 && !c++11 && !c++14 && !c++17 && !c++20) && using-built-library-before-llvm-18
#include <fstream>
#include <cstddef>
#include <cassert>
#include "test_macros.h"
template <class CharT>
static std::size_t file_size(const char* filename) {
FILE* f = std::fopen(filename, "rb");
std::fseek(f, 0, SEEK_END);
long result = std::ftell(f);
std::fclose(f);
return result;
}
// Helper class to expose some protected std::basic_filebuf<CharT> members.
template <class CharT>
struct filebuf : public std::basic_filebuf<CharT> {
CharT* base() { return this->pbase(); }
CharT* ptr() { return this->pptr(); }
};
template <class CharT>
static void buffered_request() {
filebuf<CharT> buffer;
CharT b[10] = {0};
assert(buffer.pubsetbuf(b, 10) == &buffer);
buffer.open("test.dat", std::ios_base::out);
buffer.sputc(CharT('a'));
assert(b[0] == 'a');
buffer.close();
assert(file_size<CharT>("test.dat") == 1);
}
template <class CharT>
static void unbuffered_request_before_open() {
filebuf<CharT> buffer;
assert(buffer.pubsetbuf(nullptr, 0) == &buffer);
assert(buffer.base() == nullptr);
assert(buffer.ptr() == nullptr);
buffer.open("test.dat", std::ios_base::out);
assert(buffer.base() == nullptr);
assert(buffer.ptr() == nullptr);
buffer.sputc(CharT('a'));
assert(buffer.base() == nullptr);
assert(buffer.ptr() == nullptr);
assert(file_size<CharT>("test.dat") == 1);
}
template <class CharT>
static void unbuffered_request_after_open() {
filebuf<CharT> buffer;
buffer.open("test.dat", std::ios_base::out);
assert(buffer.pubsetbuf(nullptr, 0) == &buffer);
assert(buffer.base() == nullptr);
assert(buffer.ptr() == nullptr);
buffer.sputc(CharT('a'));
assert(buffer.base() == nullptr);
assert(buffer.ptr() == nullptr);
assert(file_size<CharT>("test.dat") == 1);
}
template <class CharT>
static void unbuffered_request_after_open_ate() {
filebuf<CharT> buffer;
buffer.open("test.dat", std::ios_base::out | std::ios_base::ate);
assert(buffer.pubsetbuf(nullptr, 0) == &buffer);
buffer.sputc(CharT('a'));
assert(file_size<CharT>("test.dat") <= 1);
// on libc++ buffering is used by default.
LIBCPP_ASSERT(file_size<CharT>("test.dat") == 0);
buffer.close();
assert(file_size<CharT>("test.dat") == 1);
}
template <class CharT>
static void test() {
buffered_request<CharT>();
unbuffered_request_before_open<CharT>();
unbuffered_request_after_open<CharT>();
unbuffered_request_after_open_ate<CharT>();
}
int main(int, char**) {
test<char>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
#endif
return 0;
}