diff options
author | asynts <asynts@gmail.com> | 2020-10-15 13:46:00 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-10-17 23:20:31 +0200 |
commit | 0508fdbbcd82deeec23cdbe5ccf139b84da21d10 (patch) | |
tree | 35c91eabccdfc25e967480b34298a793f6b86aeb | |
parent | a274a8e5a079c105ee070efd0f90cdc6d9e95847 (diff) | |
download | serenity-0508fdbbcd82deeec23cdbe5ccf139b84da21d10.zip |
AK+Format: Add outln(FILE*, ...) overload.
This commit also removes a few functions like raw_out and vwarn. If we
want to write raw output, we can do this as follows:
out("{}", "Hello, World!");
The vout stuff isn't really public API anyways, so no need for another
vwarn.
-rw-r--r-- | AK/Format.cpp | 31 | ||||
-rw-r--r-- | AK/Format.h | 41 | ||||
-rw-r--r-- | AK/Tests/TestFormat.cpp | 21 |
3 files changed, 49 insertions, 44 deletions
diff --git a/AK/Format.cpp b/AK/Format.cpp index 689a66899f..84ced59711 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -572,37 +572,18 @@ void Formatter<bool>::format(TypeErasedFormatParams& params, FormatBuilder& buil } #ifndef KERNEL -void raw_out(StringView string) -{ - const auto retval = ::fwrite(string.characters_without_null_termination(), 1, string.length(), stdout); - ASSERT(retval == string.length()); -} -void vout(StringView fmtstr, TypeErasedFormatParams params, bool newline) +void vout(FILE* file, StringView fmtstr, TypeErasedFormatParams params, bool newline) { StringBuilder builder; vformat(builder, fmtstr, params); - if (newline && !builder.is_empty()) + if (newline) builder.append('\n'); - raw_out(builder.to_string()); -} - -void raw_warn(StringView string) -{ - const auto retval = ::write(STDERR_FILENO, string.characters_without_null_termination(), string.length()); + const auto string = builder.string_view(); + const auto retval = ::fwrite(string.characters_without_null_termination(), 1, string.length(), file); ASSERT(static_cast<size_t>(retval) == string.length()); } -void vwarn(StringView fmtstr, TypeErasedFormatParams params, bool newline) -{ - StringBuilder builder; - vformat(builder, fmtstr, params); - - if (newline && !builder.is_empty()) - builder.append('\n'); - - raw_warn(builder.to_string()); -} #endif void vdbgln(StringView fmtstr, TypeErasedFormatParams params) @@ -636,9 +617,9 @@ void vdbgln(StringView fmtstr, TypeErasedFormatParams params) vformat(builder, fmtstr, params); builder.append('\n'); - const auto string = builder.build(); + const auto string = builder.string_view(); - const auto retval = dbgputstr(string.characters(), string.length()); + const auto retval = dbgputstr(string.characters_without_null_termination(), string.length()); ASSERT(retval == 0); } diff --git a/AK/Format.h b/AK/Format.h index 4bd3a4f4d9..c3334ca110 100644 --- a/AK/Format.h +++ b/AK/Format.h @@ -30,9 +30,9 @@ #include <AK/GenericLexer.h> #include <AK/StringView.h> -// FIXME: I would really love to merge the format_value and make_type_erased_parameters functions, -// but the compiler creates weird error messages when I do that. Here is a small snippet that -// reproduces the issue: https://godbolt.org/z/o55crs +#ifndef KERNEL +# include <stdio.h> +#endif namespace AK { @@ -307,29 +307,34 @@ void vformat(StringBuilder& builder, StringView fmtstr, TypeErasedFormatParams); void vformat(const LogStream& stream, StringView fmtstr, TypeErasedFormatParams); #ifndef KERNEL -void vout(StringView fmtstr, TypeErasedFormatParams, bool newline = false); -void raw_out(StringView string); +void vout(FILE*, StringView fmtstr, TypeErasedFormatParams, bool newline = false); -// FIXME: Rename this function to 'out' when that name becomes avaliable. +// FIXME: Rename 'new_out' to 'out' when the name becomes avaliable. template<typename... Parameters> -void new_out(StringView fmtstr, const Parameters&... parameters) { vout(fmtstr, VariadicFormatParams { parameters... }); } +void new_out(FILE* file, StringView fmtstr, const Parameters&... parameters) { vout(file, fmtstr, VariadicFormatParams { parameters... }); } template<typename... Parameters> -void outln(StringView fmtstr, const Parameters&... parameters) { vout(fmtstr, VariadicFormatParams { parameters... }, true); } +void outln(FILE* file, StringView fmtstr, const Parameters&... parameters) { vout(file, fmtstr, VariadicFormatParams { parameters... }, true); } template<typename... Parameters> -void outln(const char* fmtstr, const Parameters&... parameters) { outln(StringView { fmtstr }, parameters...); } -inline void outln() { raw_out("\n"); } +void outln(FILE* file, const char* fmtstr, const Parameters&... parameters) { vout(file, fmtstr, VariadicFormatParams { parameters... }, true); } +inline void outln(FILE* file) { fputc('\n', file); } -void vwarn(StringView fmtstr, TypeErasedFormatParams, bool newline = false); -void raw_warn(StringView string); +// FIXME: Rename 'new_out' to 'out' when the name becomes avaliable. +template<typename... Parameters> +void new_out(StringView fmtstr, const Parameters&... parameters) { new_out(stdout, fmtstr, parameters...); } +template<typename... Parameters> +void outln(StringView fmtstr, const Parameters&... parameters) { outln(stdout, fmtstr, parameters...); } +template<typename... Parameters> +void outln(const char* fmtstr, const Parameters&... parameters) { outln(stdout, fmtstr, parameters...); } +inline void outln() { outln(stdout); } -// FIXME: Rename this function to 'warn' when that name becomes avaliable. +// FIXME: Rename 'new_warn' to 'warn' when the name becomes avaliable. template<typename... Parameters> -void new_warn(StringView fmtstr, const Parameters&... parameters) { vwarn(fmtstr, VariadicFormatParams { parameters... }); } +void new_warn(StringView fmtstr, const Parameters&... parameters) { new_out(stderr, fmtstr, parameters...); } template<typename... Parameters> -void warnln(StringView fmtstr, const Parameters&... parameters) { vwarn(fmtstr, VariadicFormatParams { parameters... }, true); } +void warnln(StringView fmtstr, const Parameters&... parameters) { outln(stderr, fmtstr, parameters...); } template<typename... Parameters> -void warnln(const char* fmtstr, const Parameters&... parameters) { warnln(StringView { fmtstr }, parameters...); } -inline void warnln() { raw_out("\n"); } +void warnln(const char* fmtstr, const Parameters&... parameters) { outln(stderr, fmtstr, parameters...); } +inline void warnln() { outln(stderr); } #endif void vdbgln(StringView fmtstr, TypeErasedFormatParams); @@ -382,10 +387,8 @@ struct Formatter<FormatIfSupported<T>> : __FormatIfSupported<T, HasFormatter<T>: #ifndef KERNEL using AK::new_out; using AK::outln; -using AK::raw_out; using AK::new_warn; -using AK::raw_warn; using AK::warnln; #endif diff --git a/AK/Tests/TestFormat.cpp b/AK/Tests/TestFormat.cpp index 7d426fb4e1..4f3f9924f3 100644 --- a/AK/Tests/TestFormat.cpp +++ b/AK/Tests/TestFormat.cpp @@ -214,4 +214,25 @@ TEST_CASE(format_if_supported) EXPECT_EQ(String::formatted("{}", FormatIfSupported { B {} }), "B"); } +TEST_CASE(file_descriptor) +{ + char filename[] = "/tmp/test-file-descriptor-XXXXXX"; + + int fd = mkstemp(filename); + FILE* file = fdopen(fd, "w+"); + + outln(file, "{}", "Hello, World!"); + new_out(file, "foo"); + outln(file, "bar"); + + rewind(file); + + Array<u8, 256> buffer; + const auto nread = fread(buffer.data(), 1, buffer.size(), file); + + EXPECT_EQ(StringView { "Hello, World!\nfoobar\n" }, StringView { buffer.span().trim(nread) }); + + fclose(file); +} + TEST_MAIN(Format) |