2024-02-21 18:10:00 +00:00
|
|
|
// { dg-additional-options "-lstdc++exp" { target { *-*-mingw* } } }
|
libstdc++: Implement C++23 <print> header [PR107760]
This adds the C++23 std::print functions, which use std::format to write
to a FILE stream or std::ostream (defaulting to stdout).
The new extern symbols are in the libstdc++exp.a archive, so we aren't
committing to stable symbols in the DSO yet. There's a UTF-8 validating
and transcoding function added by this change. That can certainly be
optimized, but it's internal to libstdc++exp.a so can be tweaked later
at leisure.
Currently the external symbols work for all targets, but are only
actually used for Windows, where it's necessary to transcode to UTF-16
to write to the console. The standard seems to encourage us to also
diagnose invalid UTF-8 for non-Windows targets when writing to a
terminal (and only when writing to a terminal), but I'm reliably
informed that that wasn't the intent of the wording. Checking for
invalid UTF-8 sequences only needs to happen for Windows, which is good
as checking for a terminal requires a call to isatty, and on Linux that
uses an ioctl syscall, which would make std::print ten times slower!
Testing the std::print behaviour is difficult if it depends on whether
the output stream is connected to a Windows console or not, as we can't
(as far as I know) do that non-interactively in DejaGNU. One of the new
tests uses the internal __write_to_terminal function directly. That
allows us to verify its UTF-8 error handling on POSIX targets, even
though that's not actually used by std::print. For Windows, that
__write_to_terminal function transcodes to UTF-16 but then uses
WriteConsoleW which fails unless it really is writing to the console.
That means the 27_io/print/2.cc test FAILs on Windows. The UTF-16
transcoding has been manually tested using mingw-w64 and Wine, and
appears to work.
libstdc++-v3/ChangeLog:
PR libstdc++/107760
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/version.def (__cpp_lib_print): Define.
* include/bits/version.h: Regenerate.
* include/std/format (__literal_encoding_is_utf8): New function.
(_Seq_sink::view()): New member function.
* include/std/ostream (vprintf_nonunicode, vprintf_unicode)
(print, println): New functions.
* include/std/print: New file.
* src/c++23/Makefile.am: Add new source file.
* src/c++23/Makefile.in: Regenerate.
* src/c++23/print.cc: New file.
* testsuite/27_io/basic_ostream/print/1.cc: New test.
* testsuite/27_io/print/1.cc: New test.
* testsuite/27_io/print/2.cc: New test.
2023-12-14 23:23:34 +00:00
|
|
|
// { dg-do run { target c++23 } }
|
|
|
|
// { dg-require-fileio "" }
|
|
|
|
|
|
|
|
#include <print>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <testsuite_hooks.h>
|
|
|
|
#include <testsuite_fs.h>
|
|
|
|
|
|
|
|
void
|
|
|
|
test_print_default()
|
|
|
|
{
|
|
|
|
std::print("H{}ll{}, {}!", 3, 0, "world");
|
|
|
|
// { dg-output "H3ll0, world!" }
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
test_println_default()
|
|
|
|
{
|
|
|
|
std::println("I walk the line");
|
2025-01-11 19:16:57 +01:00
|
|
|
// { dg-output "I walk the line\r?\n" }
|
libstdc++: Implement C++23 <print> header [PR107760]
This adds the C++23 std::print functions, which use std::format to write
to a FILE stream or std::ostream (defaulting to stdout).
The new extern symbols are in the libstdc++exp.a archive, so we aren't
committing to stable symbols in the DSO yet. There's a UTF-8 validating
and transcoding function added by this change. That can certainly be
optimized, but it's internal to libstdc++exp.a so can be tweaked later
at leisure.
Currently the external symbols work for all targets, but are only
actually used for Windows, where it's necessary to transcode to UTF-16
to write to the console. The standard seems to encourage us to also
diagnose invalid UTF-8 for non-Windows targets when writing to a
terminal (and only when writing to a terminal), but I'm reliably
informed that that wasn't the intent of the wording. Checking for
invalid UTF-8 sequences only needs to happen for Windows, which is good
as checking for a terminal requires a call to isatty, and on Linux that
uses an ioctl syscall, which would make std::print ten times slower!
Testing the std::print behaviour is difficult if it depends on whether
the output stream is connected to a Windows console or not, as we can't
(as far as I know) do that non-interactively in DejaGNU. One of the new
tests uses the internal __write_to_terminal function directly. That
allows us to verify its UTF-8 error handling on POSIX targets, even
though that's not actually used by std::print. For Windows, that
__write_to_terminal function transcodes to UTF-16 but then uses
WriteConsoleW which fails unless it really is writing to the console.
That means the 27_io/print/2.cc test FAILs on Windows. The UTF-16
transcoding has been manually tested using mingw-w64 and Wine, and
appears to work.
libstdc++-v3/ChangeLog:
PR libstdc++/107760
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/version.def (__cpp_lib_print): Define.
* include/bits/version.h: Regenerate.
* include/std/format (__literal_encoding_is_utf8): New function.
(_Seq_sink::view()): New member function.
* include/std/ostream (vprintf_nonunicode, vprintf_unicode)
(print, println): New functions.
* include/std/print: New file.
* src/c++23/Makefile.am: Add new source file.
* src/c++23/Makefile.in: Regenerate.
* src/c++23/print.cc: New file.
* testsuite/27_io/basic_ostream/print/1.cc: New test.
* testsuite/27_io/print/1.cc: New test.
* testsuite/27_io/print/2.cc: New test.
2023-12-14 23:23:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
test_print_file()
|
|
|
|
{
|
|
|
|
__gnu_test::scoped_file f;
|
|
|
|
FILE* strm = std::fopen(f.path.string().c_str(), "w");
|
|
|
|
VERIFY( strm );
|
|
|
|
std::print(strm, "File under '{}' for {}", 'O', "OUT OF FILE");
|
|
|
|
std::fclose(strm);
|
|
|
|
|
|
|
|
std::ifstream in(f.path);
|
|
|
|
std::string txt(std::istreambuf_iterator<char>(in), {});
|
|
|
|
VERIFY( txt == "File under 'O' for OUT OF FILE" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
test_println_file()
|
|
|
|
{
|
|
|
|
__gnu_test::scoped_file f;
|
|
|
|
FILE* strm = std::fopen(f.path.string().c_str(), "w");
|
|
|
|
VERIFY( strm );
|
|
|
|
std::println(strm, "{} Lineman was a song I once heard", "Wichita");
|
|
|
|
std::fclose(strm);
|
|
|
|
|
|
|
|
std::ifstream in(f.path);
|
|
|
|
std::string txt(std::istreambuf_iterator<char>(in), {});
|
|
|
|
VERIFY( txt == "Wichita Lineman was a song I once heard\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
test_print_raw()
|
|
|
|
{
|
|
|
|
__gnu_test::scoped_file f;
|
|
|
|
FILE* strm = std::fopen(f.path.string().c_str(), "w");
|
|
|
|
VERIFY( strm );
|
|
|
|
std::print(strm, "{}", '\xa3'); // Not a valid UTF-8 string.
|
|
|
|
std::fclose(strm);
|
|
|
|
|
|
|
|
std::ifstream in(f.path);
|
|
|
|
std::string txt(std::istreambuf_iterator<char>(in), {});
|
|
|
|
// Invalid UTF-8 should be written out unchanged if the stream is not
|
|
|
|
// connected to a tty:
|
|
|
|
VERIFY( txt == "\xa3" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
test_vprint_nonunicode()
|
|
|
|
{
|
|
|
|
std::vprint_nonunicode("{0} in \xc0 {0} out\n",
|
|
|
|
std::make_format_args("garbage"));
|
|
|
|
// { dg-output "garbage in . garbage out" }
|
|
|
|
}
|
|
|
|
|
2024-02-22 13:06:59 +00:00
|
|
|
void
|
|
|
|
test_errors()
|
|
|
|
{
|
|
|
|
#ifdef __cpp_exceptions
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::print(stdin, "{}", "nope");
|
|
|
|
VERIFY(false);
|
|
|
|
}
|
|
|
|
catch (const std::system_error&)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
libstdc++: Implement C++23 <print> header [PR107760]
This adds the C++23 std::print functions, which use std::format to write
to a FILE stream or std::ostream (defaulting to stdout).
The new extern symbols are in the libstdc++exp.a archive, so we aren't
committing to stable symbols in the DSO yet. There's a UTF-8 validating
and transcoding function added by this change. That can certainly be
optimized, but it's internal to libstdc++exp.a so can be tweaked later
at leisure.
Currently the external symbols work for all targets, but are only
actually used for Windows, where it's necessary to transcode to UTF-16
to write to the console. The standard seems to encourage us to also
diagnose invalid UTF-8 for non-Windows targets when writing to a
terminal (and only when writing to a terminal), but I'm reliably
informed that that wasn't the intent of the wording. Checking for
invalid UTF-8 sequences only needs to happen for Windows, which is good
as checking for a terminal requires a call to isatty, and on Linux that
uses an ioctl syscall, which would make std::print ten times slower!
Testing the std::print behaviour is difficult if it depends on whether
the output stream is connected to a Windows console or not, as we can't
(as far as I know) do that non-interactively in DejaGNU. One of the new
tests uses the internal __write_to_terminal function directly. That
allows us to verify its UTF-8 error handling on POSIX targets, even
though that's not actually used by std::print. For Windows, that
__write_to_terminal function transcodes to UTF-16 but then uses
WriteConsoleW which fails unless it really is writing to the console.
That means the 27_io/print/2.cc test FAILs on Windows. The UTF-16
transcoding has been manually tested using mingw-w64 and Wine, and
appears to work.
libstdc++-v3/ChangeLog:
PR libstdc++/107760
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/version.def (__cpp_lib_print): Define.
* include/bits/version.h: Regenerate.
* include/std/format (__literal_encoding_is_utf8): New function.
(_Seq_sink::view()): New member function.
* include/std/ostream (vprintf_nonunicode, vprintf_unicode)
(print, println): New functions.
* include/std/print: New file.
* src/c++23/Makefile.am: Add new source file.
* src/c++23/Makefile.in: Regenerate.
* src/c++23/print.cc: New file.
* testsuite/27_io/basic_ostream/print/1.cc: New test.
* testsuite/27_io/print/1.cc: New test.
* testsuite/27_io/print/2.cc: New test.
2023-12-14 23:23:34 +00:00
|
|
|
int main()
|
|
|
|
{
|
|
|
|
test_print_default();
|
|
|
|
test_println_default();
|
|
|
|
test_print_file();
|
|
|
|
test_println_file();
|
|
|
|
test_print_raw();
|
|
|
|
test_vprint_nonunicode();
|
2024-02-22 13:06:59 +00:00
|
|
|
test_errors();
|
libstdc++: Implement C++23 <print> header [PR107760]
This adds the C++23 std::print functions, which use std::format to write
to a FILE stream or std::ostream (defaulting to stdout).
The new extern symbols are in the libstdc++exp.a archive, so we aren't
committing to stable symbols in the DSO yet. There's a UTF-8 validating
and transcoding function added by this change. That can certainly be
optimized, but it's internal to libstdc++exp.a so can be tweaked later
at leisure.
Currently the external symbols work for all targets, but are only
actually used for Windows, where it's necessary to transcode to UTF-16
to write to the console. The standard seems to encourage us to also
diagnose invalid UTF-8 for non-Windows targets when writing to a
terminal (and only when writing to a terminal), but I'm reliably
informed that that wasn't the intent of the wording. Checking for
invalid UTF-8 sequences only needs to happen for Windows, which is good
as checking for a terminal requires a call to isatty, and on Linux that
uses an ioctl syscall, which would make std::print ten times slower!
Testing the std::print behaviour is difficult if it depends on whether
the output stream is connected to a Windows console or not, as we can't
(as far as I know) do that non-interactively in DejaGNU. One of the new
tests uses the internal __write_to_terminal function directly. That
allows us to verify its UTF-8 error handling on POSIX targets, even
though that's not actually used by std::print. For Windows, that
__write_to_terminal function transcodes to UTF-16 but then uses
WriteConsoleW which fails unless it really is writing to the console.
That means the 27_io/print/2.cc test FAILs on Windows. The UTF-16
transcoding has been manually tested using mingw-w64 and Wine, and
appears to work.
libstdc++-v3/ChangeLog:
PR libstdc++/107760
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/version.def (__cpp_lib_print): Define.
* include/bits/version.h: Regenerate.
* include/std/format (__literal_encoding_is_utf8): New function.
(_Seq_sink::view()): New member function.
* include/std/ostream (vprintf_nonunicode, vprintf_unicode)
(print, println): New functions.
* include/std/print: New file.
* src/c++23/Makefile.am: Add new source file.
* src/c++23/Makefile.in: Regenerate.
* src/c++23/print.cc: New file.
* testsuite/27_io/basic_ostream/print/1.cc: New test.
* testsuite/27_io/print/1.cc: New test.
* testsuite/27_io/print/2.cc: New test.
2023-12-14 23:23:34 +00:00
|
|
|
}
|