diff options
author | Mark de Wever <koraq@xs4all.nl> | 2023-07-12 08:20:26 +0200 |
---|---|---|
committer | Mark de Wever <koraq@xs4all.nl> | 2023-07-22 11:28:17 +0200 |
commit | e2953303f4d3855a4700f8cc7d5a6aa5fb4af8fb (patch) | |
tree | 19554e1e4b50ad3056dfb61615a4374f7b2fd5e9 /libcxx | |
parent | c51c607dfc6388050ed1381a32089cd08a36ff9a (diff) | |
download | llvm-e2953303f4d3855a4700f8cc7d5a6aa5fb4af8fb.zip llvm-e2953303f4d3855a4700f8cc7d5a6aa5fb4af8fb.tar.gz llvm-e2953303f4d3855a4700f8cc7d5a6aa5fb4af8fb.tar.bz2 |
[libc++][print] Adds stdout functions.
Implements parts of
- P2093R14 Formatted output
- P2539R4 Should the output of std::print to a terminal be
synchronized with the underlying stream?
Depends on D150044
Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D155262
Diffstat (limited to 'libcxx')
8 files changed, 218 insertions, 4 deletions
diff --git a/libcxx/docs/Status/FormatPaper.csv b/libcxx/docs/Status/FormatPaper.csv index 4d44db8..0acde33 100644 --- a/libcxx/docs/Status/FormatPaper.csv +++ b/libcxx/docs/Status/FormatPaper.csv @@ -47,6 +47,6 @@ Section,Description,Dependencies,Assignee,Status,First released version `[stacktrace.format] <https://wg21.link/stacktrace.format>`_,"Formatting ``stacktrace``",A ``<stacktrace>`` implementation,Mark de Wever,, "`P2093R14 <https://wg21.link/P2093R14>`__","Formatted output" -`[print.fun] <https://wg21.link/print.fun>`__,"Output to ``stdout``",,Mark de Wever,|In Progress|, +`[print.fun] <https://wg21.link/print.fun>`__,"Output to ``stdout``",,Mark de Wever,|Complete|, 17.0 `[print.fun] <https://wg21.link/print.fun>`__,"Output to ``FILE*``",,Mark de Wever,|Complete|, 17.0 `[ostream.formatted.print] <https://wg21.link/ostream.formatted.print>`__,"Output to ``ostream``",,Mark de Wever diff --git a/libcxx/include/print b/libcxx/include/print index 97f0047..d119c8b 100644 --- a/libcxx/include/print +++ b/libcxx/include/print @@ -14,13 +14,19 @@ namespace std { // [print.fun], print functions template<class... Args> + void print(format_string<Args...> fmt, Args&&... args); + template<class... Args> void print(FILE* stream, format_string<Args...> fmt, Args&&... args); template<class... Args> + void println(format_string<Args...> fmt, Args&&... args); + template<class... Args> void println(FILE* stream, format_string<Args...> fmt, Args&&... args); + void vprint_unicode(string_view fmt, format_args args); void vprint_unicode(FILE* stream, string_view fmt, format_args args); + void vprint_nonunicode(string_view fmt, format_args args); void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); } */ @@ -329,6 +335,11 @@ _LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, } template <class... _Args> +_LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __args) { + std::print(stdout, __fmt, std::forward<_Args>(__args)...); +} + +template <class... _Args> _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) { # ifndef _LIBCPP_HAS_NO_UNICODE // Note the wording in the Standard is inefficient. The output of @@ -343,11 +354,22 @@ _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt # endif // _LIBCPP_HAS_NO_UNICODE } +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) { + std::println(stdout, __fmt, std::forward<_Args>(__args)...); +} + # ifndef _LIBCPP_HAS_NO_UNICODE template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) { __print::__vprint_unicode(__stream, __fmt, __args, false); } + +template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). +_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) { + std::vprint_unicode(stdout, __fmt, __args); +} + # endif // _LIBCPP_HAS_NO_UNICODE template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). @@ -355,6 +377,11 @@ _LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __print::__vprint_nonunicode(__stream, __fmt, __args, false); } +template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). +_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(string_view __fmt, format_args __args) { + std::vprint_nonunicode(stdout, __fmt, __args); +} + #endif // _LIBCPP_STD_VER >= 23 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/echo.sh b/libcxx/test/std/input.output/iostream.format/print.fun/echo.sh new file mode 100644 index 0000000..12a2d93 --- /dev/null +++ b/libcxx/test/std/input.output/iostream.format/print.fun/echo.sh @@ -0,0 +1 @@ +echo ${1} ${2} diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/print.sh.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/print.sh.cpp new file mode 100644 index 0000000..405156f --- /dev/null +++ b/libcxx/test/std/input.output/iostream.format/print.fun/print.sh.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: executor-has-no-bash +// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME + +// XFAIL: availability-fp_to_chars-missing + +// <print> + +// template<class... Args> +// void print(format_string<Args...> fmt, Args&&... args); + +// Testing this properly is quite hard; the function unconditionally +// writes to stdout. When stdout is redirected to a file it is no longer +// considered a terminal. The function is a small wrapper around +// +// template<class... Args> +// void print(FILE* stream, format_string<Args...> fmt, Args&&... args); +// +// So do minimal tests for this function and rely on the FILE* overload +// to do more testing. +// +// The testing is based on the testing for std::cout. + +// TODO PRINT Use lit builtin echo + +// FILE_DEPENDENCIES: echo.sh +// RUN: %{build} +// RUN: %{exec} bash echo.sh -n "1234 一二三四 true 0x0" > %t.expected +// RUN: %{exec} "%t.exe" > %t.actual +// RUN: diff -u %t.actual %t.expected + +#include <print> + +int main(int, char**) { + // The data is passed as-is so it does not depend on the encoding of the input. + std::print("{} {} ", 1234, "一二三四"); + std::print("{} {}", true, nullptr); + + return 0; +} diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/println.sh.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/println.sh.cpp new file mode 100644 index 0000000..f0b2a54 --- /dev/null +++ b/libcxx/test/std/input.output/iostream.format/print.fun/println.sh.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: executor-has-no-bash +// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME + +// FIXME PRINT How to test println on Windows? +// XFAIL: msvc, target={{.+}}-windows-gnu + +// XFAIL: availability-fp_to_chars-missing + +// <print> + +// template<class... Args> +// void println(format_string<Args...> fmt, Args&&... args); + +// Testing this properly is quite hard; the function unconditionally +// writes to stdout. When stdout is redirected to a file it is no longer +// considered a terminal. The function is a small wrapper around +// +// template<class... Args> +// void println(FILE* stream, format_string<Args...> fmt, Args&&... args); +// +// So do minimal tests for this function and rely on the FILE* overload +// to do more testing. +// +// The testing is based on the testing for std::cout. + +// TODO PRINT Use lit builtin echo + +// FILE_DEPENDENCIES: echo.sh +// RUN: %{build} +// RUN: %{exec} bash echo.sh -ne "1234 一二三四\ntrue 0x0\n" > %t.expected +// RUN: %{exec} "%t.exe" > %t.actual +// RUN: diff -u %t.actual %t.expected + +#include <print> + +int main(int, char**) { + // The data is passed as-is so it does not depend on the encoding of the input. + std::println("{} {}", 1234, "一二三四"); + std::println("{} {}", true, nullptr); + + return 0; +} diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.sh.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.sh.cpp new file mode 100644 index 0000000..5d63c94 --- /dev/null +++ b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.sh.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: executor-has-no-bash +// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME + +// XFAIL: availability-fp_to_chars-missing + +// <print> + +// void vprint_nonunicode(string_view fmt, format_args args); + +// Testing this properly is quite hard; the function unconditionally +// writes to stdout. When stdout is redirected to a file it is no longer +// considered a terminal. The function is a small wrapper around +// +// void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); +// +// So do minimal tests for this function and rely on the FILE* overload +// to do more testing. +// +// The testing is based on the testing for std::cout. + +// TODO PRINT Use lit builtin echo + +// FILE_DEPENDENCIES: echo.sh +// RUN: %{build} +// RUN: %{exec} bash echo.sh -n "1234 一二三四 true 0x0" > %t.expected +// RUN: %{exec} "%t.exe" > %t.actual +// RUN: diff -u %t.actual %t.expected + +#include <print> + +int main(int, char**) { + // The data is passed as-is so it does not depend on the encoding of the input. + std::vprint_nonunicode("{} {} ", std::make_format_args(1234, "一二三四")); + std::vprint_nonunicode("{} {}", std::make_format_args(true, nullptr)); + + return 0; +} diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.sh.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.sh.cpp new file mode 100644 index 0000000..cbfb672 --- /dev/null +++ b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.sh.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: executor-has-no-bash +// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME + +// XFAIL: availability-fp_to_chars-missing + +// <print> + +// void vprint_unicode(string_view fmt, format_args args); + +// Testing this properly is quite hard; the function unconditionally +// writes to stdout. When stdout is redirected to a file it is no longer +// considered a terminal. The function is a small wrapper around +// +// void vprint_unicode(FILE* stream, string_view fmt, format_args args); +// +// So do minimal tests for this function and rely on the FILE* overload +// to do more testing. +// +// The testing is based on the testing for std::cout. + +// TODO PRINT Use lit builtin echo + +// FILE_DEPENDENCIES: echo.sh +// RUN: %{build} +// RUN: %{exec} bash echo.sh -n "1234 一二三四 true 0x0" > %t.expected +// RUN: %{exec} "%t.exe" > %t.actual +// RUN: diff -u %t.actual %t.expected + +#include <print> + +int main(int, char**) { + // The data is passed as-is so it does not depend on the encoding of the input. + std::vprint_unicode("{} {} ", std::make_format_args(1234, "一二三四")); + std::vprint_unicode("{} {}", std::make_format_args(true, nullptr)); + + return 0; +} diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot index c8954d3..e70a7d3 100755 --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -238,17 +238,16 @@ check-generated-output) # Depends on LC_COLLATE set at the top of this script. ! grep -rn '[^ -~]' libcxx/include libcxx/src libcxx/test libcxx/benchmarks \ --exclude '*.dat' \ + --exclude '*unicode*.cpp' \ + --exclude '*print*.sh.cpp' \ --exclude 'escaped_output.*.pass.cpp' \ - --exclude 'fill.unicode.pass.cpp' \ --exclude 'format_tests.h' \ --exclude 'format.functions.tests.h' \ --exclude 'formatter.*.pass.cpp' \ --exclude 'grep.pass.cpp' \ --exclude 'locale-specific_form.pass.cpp' \ --exclude 'ostream.pass.cpp' \ - --exclude 'std_format_spec_string_unicode.bench.cpp' \ --exclude 'transcoding.pass.cpp' \ - --exclude 'vprint_unicode_windows.pass.cpp' \ --exclude 'underflow.pass.cpp' \ || false |