libos: Add ways to format output to a File

This commit is contained in:
apio 2024-03-29 14:41:45 +01:00
parent d70effd1db
commit f9b39c5ff3
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 77 additions and 37 deletions

View File

@ -9,6 +9,7 @@
#pragma once #pragma once
#include <fcntl.h> #include <fcntl.h>
#include <luna/Attributes.h>
#include <luna/Buffer.h> #include <luna/Buffer.h>
#include <luna/Result.h> #include <luna/Result.h>
#include <luna/SharedPtr.h> #include <luna/SharedPtr.h>
@ -126,6 +127,24 @@ namespace os
*/ */
Result<void> write(const Buffer& buf); Result<void> write(const Buffer& buf);
/**
* @brief Write a formatted string to this File.
*
* @param format The format string.
* @param ... The format arguments.
* @return Result<void> Whether the operation succeeded.
*/
Result<usize> write_formatted(const char* format, ...) _format(2, 3);
/**
* @brief Write a formatted string to this File.
*
* @param format The format string.
* @param args The format arguments.
* @return Result<void> Whether the operation succeeded.
*/
Result<usize> write_vformatted(const char* format, va_list args);
/** /**
* @brief Read a line from this File. * @brief Read a line from this File.
* *
@ -247,36 +266,36 @@ namespace os
/** /**
* @brief Print a formatted string to standard output. * @brief Print a formatted string to standard output.
* *
* @param fmt The format string (in the same format as printf(3)). * @param format The format string (in the same format as printf(3)).
* @param ... The format arguments. * @param ... The format arguments.
* @return Result<void> Whether the operation succeeded. * @return Result<void> Whether the operation succeeded.
*/ */
Result<void> print(StringView fmt, ...); Result<void> print(const char* format, ...) _format(1, 2);
/** /**
* @brief Print a newline-terminated formatted string to standard output. * @brief Print a newline-terminated formatted string to standard output.
* *
* @param fmt The format string (in the same format as printf(3)). * @param format The format string (in the same format as printf(3)).
* @param ... The format arguments. * @param ... The format arguments.
* @return Result<void> Whether the operation succeeded. * @return Result<void> Whether the operation succeeded.
*/ */
Result<void> println(StringView fmt, ...); Result<void> println(const char* format, ...) _format(1, 2);
/** /**
* @brief Print a formatted string to standard error. * @brief Print a formatted string to standard error.
* *
* @param fmt The format string (in the same format as printf(3)). * @param format The format string (in the same format as printf(3)).
* @param ... The format arguments. * @param ... The format arguments.
* @return Result<void> Whether the operation succeeded. * @return Result<void> Whether the operation succeeded.
*/ */
Result<void> eprint(StringView fmt, ...); Result<void> eprint(const char* format, ...) _format(1, 2);
/** /**
* @brief Print a newline-terminated formatted string to standard error. * @brief Print a newline-terminated formatted string to standard error.
* *
* @param fmt The format string (in the same format as printf(3)). * @param format The format string (in the same format as printf(3)).
* @param ... The format arguments. * @param ... The format arguments.
* @return Result<void> Whether the operation succeeded. * @return Result<void> Whether the operation succeeded.
*/ */
Result<void> eprintln(StringView fmt, ...); Result<void> eprintln(const char* format, ...) _format(1, 2);
} }

View File

@ -8,6 +8,7 @@
*/ */
#include <errno.h> #include <errno.h>
#include <luna/Format.h>
#include <luna/StringBuilder.h> #include <luna/StringBuilder.h>
#include <os/File.h> #include <os/File.h>
#include <unistd.h> #include <unistd.h>
@ -141,6 +142,33 @@ namespace os
return {}; return {};
} }
Result<usize> File::write_formatted(const char* format, ...)
{
va_list ap;
va_start(ap, format);
auto result = write_vformatted(format, ap);
va_end(ap);
return result;
}
Result<usize> File::write_vformatted(const char* format, va_list args)
{
auto rc = TRY(cstyle_format(
format,
[](char c, void* f) -> Result<void> {
TRY(((File*)f)->raw_write((const u8*)&c, 1));
return {};
},
this, args));
flush();
return rc;
}
Result<String> File::read_line() Result<String> File::read_line()
{ {
Vector<char> data; Vector<char> data;
@ -246,64 +274,57 @@ namespace os
setvbuf(m_file, NULL, mode, 0); setvbuf(m_file, NULL, mode, 0);
} }
// FIXME: Do not allocate memory for printing. Result<void> print(const char* format, ...)
Result<void> print_impl(SharedPtr<File> f, StringView fmt, va_list ap)
{
auto str = TRY(String::vformat(fmt, ap));
auto rc = f->write(str.view());
f->flush();
return rc;
}
Result<void> print(StringView fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, format);
auto rc = print_impl(File::standard_output(), fmt, ap); TRY(File::standard_output()->write_vformatted(format, ap));
va_end(ap); va_end(ap);
return rc; return {};
} }
Result<void> println(StringView fmt, ...) Result<void> println(const char* format, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, format);
auto rc = print_impl(File::standard_output(), fmt, ap); auto file = File::standard_output();
TRY(file->write_vformatted(format, ap));
TRY(file->write("\n"_sv));
va_end(ap); va_end(ap);
TRY(rc); return {};
return File::standard_output()->write("\n"_sv);
} }
Result<void> eprint(StringView fmt, ...) Result<void> eprint(const char* format, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, format);
auto rc = print_impl(File::standard_error(), fmt, ap); TRY(File::standard_error()->write_vformatted(format, ap));
va_end(ap); va_end(ap);
return rc; return {};
} }
Result<void> eprintln(StringView fmt, ...) Result<void> eprintln(const char* format, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, format);
auto rc = print_impl(File::standard_error(), fmt, ap); auto file = File::standard_error();
TRY(file->write_vformatted(format, ap));
TRY(file->write("\n"_sv));
va_end(ap); va_end(ap);
TRY(rc); return {};
return File::standard_error()->write("\n"_sv);
} }
} }