From 11d643f0b11c041d7030d43a328adf2eb3ba4e3d Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Fri, 7 Jun 2024 11:37:12 -0700 Subject: [libc] Add baremetal printf (#94078) For baremetal targets that don't support FILE, this version of printf just writes directly to a function provided by a vendor. To do this both printf and vprintf were moved to /generic (vprintf since they need the same flags and cmake gets funky about setting variables in one file and reading them in another). --- libc/src/stdio/CMakeLists.txt | 35 ++------------------ libc/src/stdio/baremetal/CMakeLists.txt | 12 +++++++ libc/src/stdio/baremetal/printf.cpp | 57 +++++++++++++++++++++++++++++++++ libc/src/stdio/generic/CMakeLists.txt | 33 +++++++++++++++++++ libc/src/stdio/generic/printf.cpp | 38 ++++++++++++++++++++++ libc/src/stdio/generic/vprintf.cpp | 36 +++++++++++++++++++++ libc/src/stdio/printf.cpp | 38 ---------------------- libc/src/stdio/vprintf.cpp | 36 --------------------- 8 files changed, 178 insertions(+), 107 deletions(-) create mode 100644 libc/src/stdio/baremetal/printf.cpp create mode 100644 libc/src/stdio/generic/printf.cpp create mode 100644 libc/src/stdio/generic/vprintf.cpp delete mode 100644 libc/src/stdio/printf.cpp delete mode 100644 libc/src/stdio/vprintf.cpp (limited to 'libc') diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt index 1056f38..ee48e44 100644 --- a/libc/src/stdio/CMakeLists.txt +++ b/libc/src/stdio/CMakeLists.txt @@ -159,29 +159,6 @@ add_entrypoint_object( libc.src.stdio.printf_core.writer ) -list(APPEND printf_deps - libc.src.__support.arg_list - libc.src.stdio.printf_core.vfprintf_internal -) - -if(LLVM_LIBC_FULL_BUILD) - list(APPEND printf_deps - libc.src.__support.File.file - libc.src.__support.File.platform_file - libc.src.__support.File.platform_stdout - ) -endif() - -add_entrypoint_object( - printf - SRCS - printf.cpp - HDRS - printf.h - DEPENDS - ${printf_deps} -) - add_entrypoint_object( fprintf SRCS @@ -216,16 +193,6 @@ add_entrypoint_object( ) add_entrypoint_object( - vprintf - SRCS - vprintf.cpp - HDRS - vprintf.h - DEPENDS - ${printf_deps} -) - -add_entrypoint_object( vfprintf SRCS vfprintf.cpp @@ -286,6 +253,7 @@ add_stdio_entrypoint_object(fwrite) add_stdio_entrypoint_object(fputc) add_stdio_entrypoint_object(putc) add_stdio_entrypoint_object(putchar) +add_stdio_entrypoint_object(printf) add_stdio_entrypoint_object(fgetc) add_stdio_entrypoint_object(fgetc_unlocked) add_stdio_entrypoint_object(getc) @@ -297,3 +265,4 @@ add_stdio_entrypoint_object(ungetc) add_stdio_entrypoint_object(stdin) add_stdio_entrypoint_object(stdout) add_stdio_entrypoint_object(stderr) +add_stdio_entrypoint_object(vprintf) diff --git a/libc/src/stdio/baremetal/CMakeLists.txt b/libc/src/stdio/baremetal/CMakeLists.txt index 6508927..a1a5ba5 100644 --- a/libc/src/stdio/baremetal/CMakeLists.txt +++ b/libc/src/stdio/baremetal/CMakeLists.txt @@ -7,3 +7,15 @@ add_entrypoint_object( DEPENDS libc.include.stdio ) + +add_entrypoint_object( + printf + SRCS + printf.cpp + HDRS + ../printf.h + DEPENDS + libc.src.stdio.printf_core.printf_main + libc.src.stdio.printf_core.writer + libc.src.__support.arg_list +) diff --git a/libc/src/stdio/baremetal/printf.cpp b/libc/src/stdio/baremetal/printf.cpp new file mode 100644 index 0000000..597078b --- /dev/null +++ b/libc/src/stdio/baremetal/printf.cpp @@ -0,0 +1,57 @@ +//===-- Implementation of printf for baremetal ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/printf.h" +#include "src/__support/arg_list.h" +#include "src/stdio/printf_core/core_structs.h" +#include "src/stdio/printf_core/printf_main.h" +#include "src/stdio/printf_core/writer.h" + +#include + +// TODO(https://github.com/llvm/llvm-project/issues/94685) unify baremetal hooks + +// This is intended to be provided by the vendor. +extern "C" size_t __llvm_libc_raw_write(const char *s, size_t size); + +namespace LIBC_NAMESPACE { + +namespace { + +LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { + size_t written = __llvm_libc_raw_write(new_str.data(), new_str.size()); + if (written != new_str.size()) + return printf_core::FILE_WRITE_ERROR; + return printf_core::WRITE_OK; +} + +} // namespace + +LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { + va_list vlist; + va_start(vlist, format); + internal::ArgList args(vlist); // This holder class allows for easier copying + // and pointer semantics, as well as handling + // destruction automatically. + va_end(vlist); + constexpr size_t BUFF_SIZE = 1024; + char buffer[BUFF_SIZE]; + + printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr); + printf_core::Writer writer(&wb); + + int retval = printf_core::printf_main(&writer, format, args); + + int flushval = wb.overflow_write(""); + if (flushval != printf_core::WRITE_OK) + retval = flushval; + + return retval; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt index ae25591..9cd4cfd 100644 --- a/libc/src/stdio/generic/CMakeLists.txt +++ b/libc/src/stdio/generic/CMakeLists.txt @@ -363,6 +363,39 @@ add_entrypoint_object( libc.src.__support.File.platform_file ) +list(APPEND printf_deps + libc.src.__support.arg_list + libc.src.stdio.printf_core.vfprintf_internal +) + +if(LLVM_LIBC_FULL_BUILD) + list(APPEND printf_deps + libc.src.__support.File.file + libc.src.__support.File.platform_file + libc.src.__support.File.platform_stdout + ) +endif() + +add_entrypoint_object( + printf + SRCS + printf.cpp + HDRS + ../printf.h + DEPENDS + ${printf_deps} +) + +add_entrypoint_object( + vprintf + SRCS + vprintf.cpp + HDRS + ../vprintf.h + DEPENDS + ${printf_deps} +) + add_entrypoint_object( fgets SRCS diff --git a/libc/src/stdio/generic/printf.cpp b/libc/src/stdio/generic/printf.cpp new file mode 100644 index 0000000..5701ca9 --- /dev/null +++ b/libc/src/stdio/generic/printf.cpp @@ -0,0 +1,38 @@ +//===-- Implementation of printf --------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/printf.h" + +#include "src/__support/File/file.h" +#include "src/__support/arg_list.h" +#include "src/stdio/printf_core/vfprintf_internal.h" + +#include +#include + +#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE +#define PRINTF_STDOUT LIBC_NAMESPACE::stdout +#else // LIBC_COPT_STDIO_USE_SYSTEM_FILE +#define PRINTF_STDOUT ::stdout +#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { + va_list vlist; + va_start(vlist, format); + internal::ArgList args(vlist); // This holder class allows for easier copying + // and pointer semantics, as well as handling + // destruction automatically. + va_end(vlist); + int ret_val = printf_core::vfprintf_internal( + reinterpret_cast<::FILE *>(PRINTF_STDOUT), format, args); + return ret_val; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/stdio/generic/vprintf.cpp b/libc/src/stdio/generic/vprintf.cpp new file mode 100644 index 0000000..eff968d --- /dev/null +++ b/libc/src/stdio/generic/vprintf.cpp @@ -0,0 +1,36 @@ +//===-- Implementation of vprintf -------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/vprintf.h" + +#include "src/__support/File/file.h" +#include "src/__support/arg_list.h" +#include "src/stdio/printf_core/vfprintf_internal.h" + +#include +#include + +#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE +#define PRINTF_STDOUT LIBC_NAMESPACE::stdout +#else // LIBC_COPT_STDIO_USE_SYSTEM_FILE +#define PRINTF_STDOUT ::stdout +#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, vprintf, + (const char *__restrict format, va_list vlist)) { + internal::ArgList args(vlist); // This holder class allows for easier copying + // and pointer semantics, as well as handling + // destruction automatically. + int ret_val = printf_core::vfprintf_internal( + reinterpret_cast<::FILE *>(PRINTF_STDOUT), format, args); + return ret_val; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/stdio/printf.cpp b/libc/src/stdio/printf.cpp deleted file mode 100644 index 5701ca9..0000000 --- a/libc/src/stdio/printf.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//===-- Implementation of printf --------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "src/stdio/printf.h" - -#include "src/__support/File/file.h" -#include "src/__support/arg_list.h" -#include "src/stdio/printf_core/vfprintf_internal.h" - -#include -#include - -#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE -#define PRINTF_STDOUT LIBC_NAMESPACE::stdout -#else // LIBC_COPT_STDIO_USE_SYSTEM_FILE -#define PRINTF_STDOUT ::stdout -#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE - -namespace LIBC_NAMESPACE { - -LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { - va_list vlist; - va_start(vlist, format); - internal::ArgList args(vlist); // This holder class allows for easier copying - // and pointer semantics, as well as handling - // destruction automatically. - va_end(vlist); - int ret_val = printf_core::vfprintf_internal( - reinterpret_cast<::FILE *>(PRINTF_STDOUT), format, args); - return ret_val; -} - -} // namespace LIBC_NAMESPACE diff --git a/libc/src/stdio/vprintf.cpp b/libc/src/stdio/vprintf.cpp deleted file mode 100644 index eff968d..0000000 --- a/libc/src/stdio/vprintf.cpp +++ /dev/null @@ -1,36 +0,0 @@ -//===-- Implementation of vprintf -------------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "src/stdio/vprintf.h" - -#include "src/__support/File/file.h" -#include "src/__support/arg_list.h" -#include "src/stdio/printf_core/vfprintf_internal.h" - -#include -#include - -#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE -#define PRINTF_STDOUT LIBC_NAMESPACE::stdout -#else // LIBC_COPT_STDIO_USE_SYSTEM_FILE -#define PRINTF_STDOUT ::stdout -#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE - -namespace LIBC_NAMESPACE { - -LLVM_LIBC_FUNCTION(int, vprintf, - (const char *__restrict format, va_list vlist)) { - internal::ArgList args(vlist); // This holder class allows for easier copying - // and pointer semantics, as well as handling - // destruction automatically. - int ret_val = printf_core::vfprintf_internal( - reinterpret_cast<::FILE *>(PRINTF_STDOUT), format, args); - return ret_val; -} - -} // namespace LIBC_NAMESPACE -- cgit v1.1