[libc++] Introduce a setting to remove fstream from the library

This allows porting the library to platforms that are able to support
<iostream> but that do not have a notion of a filesystem, and where it
hence doesn't make sense to support std::fstream (and never will).

Also, remove reliance on <fstream> in various tests that didn't
actually need it.

Differential Revision: https://reviews.llvm.org/D138327
This commit is contained in:
Louis Dionne 2022-11-18 15:01:33 -05:00
parent 242a9cf7e6
commit af8c49dc1e
30 changed files with 149 additions and 120 deletions

View File

@ -84,6 +84,8 @@ option(LIBCXX_ENABLE_LOCALIZATION
the C locale API (e.g. embedded). When localization is not supported, the C locale API (e.g. embedded). When localization is not supported,
several parts of the library will be disabled: <iostream>, <regex>, <locale> several parts of the library will be disabled: <iostream>, <regex>, <locale>
will be completely unusable, and other parts may be only partly available." ON) will be completely unusable, and other parts may be only partly available." ON)
option(LIBCXX_ENABLE_FSTREAM
"Whether to include support for <fstream>." ON) # TODO: Consider rolling that into LIBCXX_ENABLE_FILESYSTEM
option(LIBCXX_ENABLE_UNICODE option(LIBCXX_ENABLE_UNICODE
"Whether to include support for Unicode in the library. Disabling Unicode can "Whether to include support for Unicode in the library. Disabling Unicode can
be useful when porting to platforms that don't support UTF-8 encoding (e.g. be useful when porting to platforms that don't support UTF-8 encoding (e.g.
@ -860,6 +862,7 @@ config_define_if(LIBCXX_ENABLE_PARALLEL_ALGORITHMS _LIBCPP_HAS_PARALLEL_ALGORITH
config_define_if_not(LIBCXX_ENABLE_FILESYSTEM _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) config_define_if_not(LIBCXX_ENABLE_FILESYSTEM _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE) config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE)
config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION) config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION)
config_define_if_not(LIBCXX_ENABLE_FSTREAM _LIBCPP_HAS_NO_FSTREAM)
config_define_if_not(LIBCXX_ENABLE_UNICODE _LIBCPP_HAS_NO_UNICODE) config_define_if_not(LIBCXX_ENABLE_UNICODE _LIBCPP_HAS_NO_UNICODE)
config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTERS) config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTERS)
config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)

View File

@ -0,0 +1 @@
set(LIBCXX_ENABLE_FSTREAM OFF CACHE BOOL "")

View File

@ -838,7 +838,7 @@ set(files
wctype.h wctype.h
) )
foreach(feature LIBCXX_ENABLE_FILESYSTEM LIBCXX_ENABLE_LOCALIZATION LIBCXX_ENABLE_THREADS LIBCXX_ENABLE_WIDE_CHARACTERS) foreach(feature LIBCXX_ENABLE_FILESYSTEM LIBCXX_ENABLE_LOCALIZATION LIBCXX_ENABLE_FSTREAM LIBCXX_ENABLE_THREADS LIBCXX_ENABLE_WIDE_CHARACTERS)
if (NOT ${${feature}}) if (NOT ${${feature}})
set(requires_${feature} "requires LIBCXX_CONFIGURED_WITHOUT_SUPPORT_FOR_THIS_HEADER") set(requires_${feature} "requires LIBCXX_CONFIGURED_WITHOUT_SUPPORT_FOR_THIS_HEADER")
endif() endif()

View File

@ -28,6 +28,7 @@
#cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS #cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS
#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE #cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE
#cmakedefine _LIBCPP_HAS_NO_LOCALIZATION #cmakedefine _LIBCPP_HAS_NO_LOCALIZATION
#cmakedefine _LIBCPP_HAS_NO_FSTREAM
#cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS #cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS
#cmakedefine01 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT #cmakedefine01 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT
#cmakedefine _LIBCPP_ENABLE_DEBUG_MODE #cmakedefine _LIBCPP_ENABLE_DEBUG_MODE

View File

@ -210,6 +210,8 @@ _LIBCPP_PUSH_MACROS
# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS # define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
#endif #endif
#if !defined(_LIBCPP_HAS_NO_FSTREAM)
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _CharT, class _Traits> template <class _CharT, class _Traits>
@ -1742,6 +1744,8 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_NO_FSTREAM
_LIBCPP_POP_MACROS _LIBCPP_POP_MACROS
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20

View File

@ -855,6 +855,7 @@ module std [system] {
} }
module fstream { module fstream {
@requires_LIBCXX_ENABLE_LOCALIZATION@ @requires_LIBCXX_ENABLE_LOCALIZATION@
@requires_LIBCXX_ENABLE_FSTREAM@
header "fstream" header "fstream"
export * export *
} }

View File

@ -36,9 +36,12 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringbuf<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>;
#ifndef _LIBCPP_HAS_NO_FSTREAM
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>;
#endif
// Add more here if needed... // Add more here if needed...

View File

@ -325,7 +325,7 @@ int main(int, char**) { return 0; }
#endif #endif
// RUN: %{build} -DTEST_51 // RUN: %{build} -DTEST_51
#if defined(TEST_51) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) #if defined(TEST_51) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
# include <fstream> # include <fstream>
using HandlerType = decltype(std::__libcpp_verbose_abort); using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif #endif

View File

@ -98,7 +98,7 @@ END-SCRIPT
#include <float.h> #include <float.h>
#include <format> #include <format>
#include <forward_list> #include <forward_list>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
# include <fstream> # include <fstream>
#endif #endif
#include <functional> #include <functional>

View File

@ -100,7 +100,7 @@ END-SCRIPT
#include <float.h> #include <float.h>
#include <format> #include <format>
#include <forward_list> #include <forward_list>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
# include <fstream> # include <fstream>
#endif #endif
#include <functional> #include <functional>

View File

@ -151,7 +151,7 @@ TEST_MACROS();
TEST_MACROS(); TEST_MACROS();
#include <forward_list> #include <forward_list>
TEST_MACROS(); TEST_MACROS();
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
# include <fstream> # include <fstream>
TEST_MACROS(); TEST_MACROS();
#endif #endif

View File

@ -251,7 +251,7 @@ END-SCRIPT
#include <forward_list> #include <forward_list>
#endif #endif
// RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_51 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_51
#if defined(TEST_51) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) #if defined(TEST_51) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
#include <fstream> #include <fstream>
#endif #endif
// RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_52 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_52

View File

@ -219,7 +219,7 @@ END-SCRIPT
#include <float.h> #include <float.h>
#include <format> #include <format>
#include <forward_list> #include <forward_list>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
# include <fstream> # include <fstream>
#endif #endif
#include <functional> #include <functional>

View File

@ -97,7 +97,7 @@ END-SCRIPT
#include <float.h> #include <float.h>
#include <format> #include <format>
#include <forward_list> #include <forward_list>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
# include <fstream> # include <fstream>
#endif #endif
#include <functional> #include <functional>

View File

@ -13,8 +13,6 @@
// pos_type seekpos(pos_type sp, // pos_type seekpos(pos_type sp,
// ios_base::openmode which = ios_base::in | ios_base::out); // ios_base::openmode which = ios_base::in | ios_base::out);
// FILE_DEPENDENCIES: underflow.dat
#include <fstream> #include <fstream>
#include <cassert> #include <cassert>

View File

@ -1,3 +1,6 @@
# All non-trivial uses of iostreams require localization support # All non-trivial uses of iostreams require localization support
if 'no-localization' in config.available_features: if 'no-localization' in config.available_features:
config.unsupported = True config.unsupported = True
if 'no-fstream' in config.available_features:
config.unsupported = True

View File

@ -17,6 +17,8 @@
// basic_streambuf, but I can't seem to reproduce without going through one // basic_streambuf, but I can't seem to reproduce without going through one
// of its derived classes. // of its derived classes.
// UNSUPPORTED: no-fstream
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>

View File

@ -19,9 +19,10 @@
// XFAIL: no-wide-characters // XFAIL: no-wide-characters
#include <locale> #include <locale>
#include <cassert>
#include <codecvt> #include <codecvt>
#include <fstream> #include <fstream>
#include <cassert> #include <sstream>
#include "test_macros.h" #include "test_macros.h"
@ -46,62 +47,73 @@ struct test_buf
int main(int, char**) int main(int, char**)
{ {
{ {
std::ofstream bs("overflow.dat"); std::string s;
test_buf f(bs.rdbuf()); {
assert(f.pbase() == 0); std::ostringstream out;
assert(f.pptr() == 0); test_buf f(out.rdbuf());
assert(f.epptr() == 0); assert(f.pbase() == 0);
assert(f.overflow(L'a') == L'a'); assert(f.pptr() == 0);
assert(f.pbase() != 0); assert(f.epptr() == 0);
assert(f.pptr() == f.pbase()); assert(f.overflow(L'a') == L'a');
assert(f.epptr() - f.pbase() == 4095); assert(f.pbase() != 0);
assert(f.pptr() == f.pbase());
assert(f.epptr() - f.pbase() == 4095);
s = out.str();
}
{
std::istringstream in(s);
test_buf f(in.rdbuf());
assert(f.sgetc() == L'a');
}
} }
{ {
std::ifstream bs("overflow.dat"); std::string s;
test_buf f(bs.rdbuf()); {
assert(f.sgetc() == L'a'); std::ostringstream out;
test_buf f(out.rdbuf());
f.pubsetbuf(0, 0);
assert(f.pbase() == 0);
assert(f.pptr() == 0);
assert(f.epptr() == 0);
assert(f.overflow('a') == 'a');
assert(f.pbase() == 0);
assert(f.pptr() == 0);
assert(f.epptr() == 0);
s = out.str();
}
{
std::istringstream in(s);
test_buf f(in.rdbuf());
assert(f.sgetc() == L'a');
}
} }
std::remove("overflow.dat"); // TODO: Move this to std::stringstream once https://llvm.org/PR59083 has been resolved
#ifndef TEST_HAS_NO_FSTREAM
{ {
std::ofstream bs("overflow.dat"); {
test_buf f(bs.rdbuf()); std::ofstream bs("overflow.dat");
f.pubsetbuf(0, 0); test_buf f(bs.rdbuf());
assert(f.pbase() == 0); assert(f.sputc(0x4E51) == 0x4E51);
assert(f.pptr() == 0); assert(f.sputc(0x4E52) == 0x4E52);
assert(f.epptr() == 0); assert(f.sputc(0x4E53) == 0x4E53);
assert(f.overflow('a') == 'a'); }
assert(f.pbase() == 0); {
assert(f.pptr() == 0); std::ifstream f("overflow.dat");
assert(f.epptr() == 0); assert(f.is_open());
assert(f.get() == 0xE4);
assert(f.get() == 0xB9);
assert(f.get() == 0x91);
assert(f.get() == 0xE4);
assert(f.get() == 0xB9);
assert(f.get() == 0x92);
assert(f.get() == 0xE4);
assert(f.get() == 0xB9);
assert(f.get() == 0x93);
assert(f.get() == -1);
}
std::remove("overflow.dat");
} }
{ #endif // TEST_HAS_NO_FSTREAM
std::ifstream bs("overflow.dat");
test_buf f(bs.rdbuf());
assert(f.sgetc() == L'a');
}
std::remove("overflow.dat");
{
std::ofstream bs("overflow.dat");
test_buf f(bs.rdbuf());
assert(f.sputc(0x4E51) == 0x4E51);
assert(f.sputc(0x4E52) == 0x4E52);
assert(f.sputc(0x4E53) == 0x4E53);
}
{
std::ifstream f("overflow.dat");
assert(f.is_open());
assert(f.get() == 0xE4);
assert(f.get() == 0xB9);
assert(f.get() == 0x91);
assert(f.get() == 0xE4);
assert(f.get() == 0xB9);
assert(f.get() == 0x92);
assert(f.get() == 0xE4);
assert(f.get() == 0xB9);
assert(f.get() == 0x93);
assert(f.get() == -1);
}
std::remove("overflow.dat");
return 0; return 0;
} }

View File

@ -6,8 +6,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// FILE_DEPENDENCIES: underflow.dat
// <locale> // <locale>
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
@ -21,11 +19,9 @@
// XFAIL: no-wide-characters // XFAIL: no-wide-characters
#include <locale> #include <locale>
#include <codecvt>
#include <fstream>
#include <cassert> #include <cassert>
#include <codecvt>
#include "test_macros.h" #include <sstream>
struct test_buf struct test_buf
: public std::wbuffer_convert<std::codecvt_utf8<wchar_t> > : public std::wbuffer_convert<std::codecvt_utf8<wchar_t> >
@ -47,16 +43,17 @@ struct test_buf
int main(int, char**) int main(int, char**)
{ {
std::string const s = "123456789";
{ {
std::ifstream bs("underflow.dat"); std::istringstream in(s);
test_buf f(bs.rdbuf()); test_buf f(in.rdbuf());
assert(f.sbumpc() == L'1'); assert(f.sbumpc() == L'1');
assert(f.sgetc() == L'2'); assert(f.sgetc() == L'2');
assert(f.pbackfail(L'a') == test_buf::traits_type::eof()); assert(f.pbackfail(L'a') == test_buf::traits_type::eof());
} }
{ {
std::fstream bs("underflow.dat"); std::istringstream in(s);
test_buf f(bs.rdbuf()); test_buf f(in.rdbuf());
assert(f.sbumpc() == L'1'); assert(f.sbumpc() == L'1');
assert(f.sgetc() == L'2'); assert(f.sgetc() == L'2');
assert(f.pbackfail(L'a') == test_buf::traits_type::eof()); assert(f.pbackfail(L'a') == test_buf::traits_type::eof());

View File

@ -21,13 +21,14 @@
// XFAIL: no-wide-characters // XFAIL: no-wide-characters
// TODO: Avoid using <fstream> in this test.
// XFAIL: no-fstream
#include <locale> #include <locale>
#include <codecvt> #include <codecvt>
#include <fstream> #include <fstream>
#include <cassert> #include <cassert>
#include "test_macros.h"
class test_codecvt class test_codecvt
: public std::codecvt<wchar_t, char, std::mbstate_t> : public std::codecvt<wchar_t, char, std::mbstate_t>
{ {

View File

@ -14,30 +14,28 @@
// XFAIL: no-wide-characters // XFAIL: no-wide-characters
#include <fstream>
#include <locale>
#include <codecvt>
#include <cassert> #include <cassert>
#include <codecvt>
#include <locale>
#include <sstream>
#include "test_macros.h" int main(int, char**) {
std::string storage;
int main(int, char**)
{
{ {
std::ofstream bytestream("myfile.txt"); std::ostringstream bytestream;
std::wbuffer_convert<std::codecvt_utf8<wchar_t> > mybuf(bytestream.rdbuf()); std::wbuffer_convert<std::codecvt_utf8<wchar_t> > mybuf(bytestream.rdbuf());
std::wostream mystr(&mybuf); std::wostream mystr(&mybuf);
mystr << L"Hello" << std::endl; mystr << L"Hello" << std::endl;
storage = bytestream.str();
} }
{ {
std::ifstream bytestream("myfile.txt"); std::istringstream bytestream(storage);
std::wbuffer_convert<std::codecvt_utf8<wchar_t> > mybuf(bytestream.rdbuf()); std::wbuffer_convert<std::codecvt_utf8<wchar_t> > mybuf(bytestream.rdbuf());
std::wistream mystr(&mybuf); std::wistream mystr(&mybuf);
std::wstring ws; std::wstring ws;
mystr >> ws; mystr >> ws;
assert(ws == L"Hello"); assert(ws == L"Hello");
} }
std::remove("myfile.txt");
return 0; return 0;
} }

View File

@ -6,8 +6,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// FILE_DEPENDENCIES: underflow.dat, underflow_utf8.dat
// <locale> // <locale>
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
@ -21,9 +19,9 @@
// XFAIL: no-wide-characters // XFAIL: no-wide-characters
#include <locale> #include <locale>
#include <codecvt>
#include <fstream>
#include <cassert> #include <cassert>
#include <codecvt>
#include <sstream>
#include "test_macros.h" #include "test_macros.h"
@ -48,7 +46,8 @@ struct test_buf
int main(int, char**) int main(int, char**)
{ {
{ {
std::ifstream bs("underflow.dat"); std::string s = "123456789";
std::istringstream bs(s);
test_buf f(bs.rdbuf()); test_buf f(bs.rdbuf());
assert(f.eback() == 0); assert(f.eback() == 0);
assert(f.gptr() == 0); assert(f.gptr() == 0);
@ -60,7 +59,8 @@ int main(int, char**)
assert(f.egptr() - f.eback() == 9); assert(f.egptr() - f.eback() == 9);
} }
{ {
std::ifstream bs("underflow.dat"); std::string s = "123456789";
std::istringstream bs(s);
test_buf f(bs.rdbuf()); test_buf f(bs.rdbuf());
assert(f.eback() == 0); assert(f.eback() == 0);
assert(f.gptr() == 0); assert(f.gptr() == 0);
@ -81,7 +81,8 @@ int main(int, char**)
assert(f.egptr() - f.gptr() == 1); assert(f.egptr() - f.gptr() == 1);
} }
{ {
std::ifstream bs("underflow_utf8.dat"); std::string s = "乑乒乓";
std::istringstream bs(s);
test_buf f(bs.rdbuf()); test_buf f(bs.rdbuf());
assert(f.sbumpc() == 0x4E51); assert(f.sbumpc() == 0x4E51);
assert(f.sbumpc() == 0x4E52); assert(f.sbumpc() == 0x4E52);
@ -89,5 +90,5 @@ int main(int, char**)
assert(f.sbumpc() == test_buf::traits_type::eof()); assert(f.sbumpc() == test_buf::traits_type::eof());
} }
return 0; return 0;
} }

View File

@ -9,7 +9,6 @@
#include <charconv> #include <charconv>
#include <chrono> #include <chrono>
#include <cmath> #include <cmath>
#include <fstream>
#include <functional> #include <functional>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
@ -49,7 +48,7 @@
using namespace std; using namespace std;
void initialize_randomness(mt19937_64& mt64, const int argc, char** const argv) { void initialize_randomness(mt19937_64& mt64, const int argc, char** const /*argv*/) {
constexpr size_t n = mt19937_64::state_size; constexpr size_t n = mt19937_64::state_size;
constexpr size_t w = mt19937_64::word_size; constexpr size_t w = mt19937_64::word_size;
static_assert(w % 32 == 0); static_assert(w % 32 == 0);
@ -59,32 +58,11 @@ void initialize_randomness(mt19937_64& mt64, const int argc, char** const argv)
puts("USAGE:"); puts("USAGE:");
puts("test.exe : generates seed data from random_device."); puts("test.exe : generates seed data from random_device.");
puts("test.exe filename.txt : loads seed data from a given text file.");
if (argc == 1) { if (argc == 1) {
random_device rd; random_device rd;
generate(vec.begin(), vec.end(), ref(rd)); generate(vec.begin(), vec.end(), ref(rd));
puts("Generated seed data."); puts("Generated seed data.");
} else if (argc == 2) {
const char* const filename = argv[1];
ifstream file(filename);
if (!file) {
printf("ERROR: Can't open %s.\n", filename);
abort();
}
for (auto& elem : vec) {
file >> elem;
if (!file) {
printf("ERROR: Can't read seed data from %s.\n", filename);
abort();
}
}
printf("Loaded seed data from %s.\n", filename);
} else { } else {
puts("ERROR: Too many command-line arguments."); puts("ERROR: Too many command-line arguments.");
abort(); abort();

View File

@ -387,6 +387,10 @@ inline void DoNotOptimize(Tp const& value) {
# define TEST_HAS_NO_FILESYSTEM_LIBRARY # define TEST_HAS_NO_FILESYSTEM_LIBRARY
#endif #endif
#if defined(_LIBCPP_HAS_NO_FSTREAM)
# define TEST_HAS_NO_FSTREAM
#endif
#if defined(_LIBCPP_HAS_NO_FGETPOS_FSETPOS) #if defined(_LIBCPP_HAS_NO_FGETPOS_FSETPOS)
# define TEST_HAS_NO_FGETPOS_FSETPOS # define TEST_HAS_NO_FGETPOS_FSETPOS
#endif #endif

View File

@ -520,6 +520,23 @@ steps:
limit: 2 limit: 2
timeout_in_minutes: 120 timeout_in_minutes: 120
- label: "No fstream"
command: "libcxx/utils/ci/run-buildbot generic-no-fstream"
artifact_paths:
- "**/test-results.xml"
- "**/*.abilist"
env:
CC: "clang-${LLVM_HEAD_VERSION}"
CXX: "clang++-${LLVM_HEAD_VERSION}"
agents:
queue: "libcxx-builders"
os: "linux"
retry:
automatic:
- exit_status: -1 # Agent was lost
limit: 2
timeout_in_minutes: 120
- label: "No locale" - label: "No locale"
command: "libcxx/utils/ci/run-buildbot generic-no-localization" command: "libcxx/utils/ci/run-buildbot generic-no-localization"
artifact_paths: artifact_paths:

View File

@ -196,6 +196,7 @@ check-generated-output)
--exclude 'locale-specific_form.pass.cpp' \ --exclude 'locale-specific_form.pass.cpp' \
--exclude 'ostream.pass.cpp' \ --exclude 'ostream.pass.cpp' \
--exclude 'std_format_spec_string_unicode.bench.cpp' \ --exclude 'std_format_spec_string_unicode.bench.cpp' \
--exclude 'underflow.pass.cpp' \
|| false || false
# Reject code with trailing whitespace # Reject code with trailing whitespace
@ -334,6 +335,11 @@ generic-no-random_device)
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-random_device.cmake" generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-random_device.cmake"
check-runtimes check-runtimes
;; ;;
generic-no-fstream)
clean
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-fstream.cmake"
check-runtimes
;;
generic-no-localization) generic-no-localization)
clean clean
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake" generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake"

View File

@ -21,7 +21,7 @@ header_restrictions = {
"clocale": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)", "clocale": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"codecvt": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)", "codecvt": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"fstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)", "fstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)",
"iomanip": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)", "iomanip": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"ios": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)", "ios": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"iostream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)", "iostream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",

View File

@ -206,6 +206,7 @@ macros = {
'_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY': 'no-filesystem', '_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY': 'no-filesystem',
'_LIBCPP_HAS_NO_RANDOM_DEVICE': 'no-random-device', '_LIBCPP_HAS_NO_RANDOM_DEVICE': 'no-random-device',
'_LIBCPP_HAS_NO_LOCALIZATION': 'no-localization', '_LIBCPP_HAS_NO_LOCALIZATION': 'no-localization',
'_LIBCPP_HAS_NO_FSTREAM': 'no-fstream',
'_LIBCPP_HAS_NO_WIDE_CHARACTERS': 'no-wide-characters', '_LIBCPP_HAS_NO_WIDE_CHARACTERS': 'no-wide-characters',
'_LIBCPP_HAS_NO_UNICODE': 'libcpp-has-no-unicode', '_LIBCPP_HAS_NO_UNICODE': 'libcpp-has-no-unicode',
'_LIBCPP_ENABLE_DEBUG_MODE': 'libcpp-has-debug-mode', '_LIBCPP_ENABLE_DEBUG_MODE': 'libcpp-has-debug-mode',