diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -280,6 +280,7 @@ libc.src.stdio.sprintf libc.src.stdio.snprintf libc.src.stdio.fprintf + libc.src.stdio.printf libc.src.stdio.stderr libc.src.stdio.stdout diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt --- a/libc/src/stdio/CMakeLists.txt +++ b/libc/src/stdio/CMakeLists.txt @@ -261,3 +261,17 @@ libc.src.__support.arg_list libc.src.stdio.printf_core.vfprintf_internal ) + + +add_entrypoint_object( + printf + SRCS + printf.cpp + HDRS + printf.h + DEPENDS + libc.src.__support.File.file + libc.src.__support.File.platform_file + libc.src.__support.arg_list + libc.src.stdio.printf_core.vfprintf_internal +) diff --git a/libc/src/stdio/printf.h b/libc/src/stdio/printf.h new file mode 100644 --- /dev/null +++ b/libc/src/stdio/printf.h @@ -0,0 +1,20 @@ +//===-- Implementation header 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_H +#define LLVM_LIBC_SRC_STDIO_PRINTF_H + +#include + +namespace __llvm_libc { + +int printf(const char *__restrict format, ...); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STDIO_PRINTF_H diff --git a/libc/src/stdio/printf.cpp b/libc/src/stdio/printf.cpp new file mode 100644 --- /dev/null +++ b/libc/src/stdio/printf.cpp @@ -0,0 +1,31 @@ +//===-- 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 + +namespace __llvm_libc { + +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 *>(__llvm_libc::stdout), format, args); + return ret_val; +} + +} // namespace __llvm_libc diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt --- a/libc/test/src/stdio/CMakeLists.txt +++ b/libc/test/src/stdio/CMakeLists.txt @@ -97,6 +97,17 @@ libc.src.stdio.fread ) + +add_libc_unittest( + printf_test + SUITE + libc_stdio_unittests + SRCS + printf_test.cpp + DEPENDS + libc.src.stdio.printf +) + add_subdirectory(printf_core) add_subdirectory(testdata) diff --git a/libc/test/src/stdio/printf_test.cpp b/libc/test/src/stdio/printf_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/stdio/printf_test.cpp @@ -0,0 +1,29 @@ +//===-- Unittests for printf ---------------------------------------------===// +// +// 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 "utils/UnitTest/Test.h" + +TEST(LlvmLibcPrintfTest, PrintOut) { + int written; + + constexpr char simple[] = "A simple string with no conversions.\n"; + written = __llvm_libc::printf(simple); + EXPECT_EQ(written, static_cast(sizeof(simple) - 1)); + + constexpr char numbers[] = "1234567890\n"; + written = __llvm_libc::printf("%s", numbers); + EXPECT_EQ(written, static_cast(sizeof(numbers) - 1)); + + constexpr char format_more[] = "%s and more\n"; + constexpr char short_numbers[] = "1234"; + written = __llvm_libc::printf(format_more, short_numbers); + EXPECT_EQ(written, + static_cast(sizeof(format_more) + sizeof(short_numbers) - 4)); +}