[libc-commits] [libc] [libc][WIP] add iprintf (PR #115194)
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Wed Nov 6 11:04:38 PST 2024
https://github.com/michaelrj-google created https://github.com/llvm/llvm-project/pull/115194
iprintf is printf without floats, clang supports this here: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp#L3392
>From 07cf7cb666203d5687cf10e47539a774907ef23e Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Wed, 6 Nov 2024 10:54:44 -0800
Subject: [PATCH] [libc][WIP] add iprintf
iprintf is printf without floats, clang supports this here: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp#L3392
---
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/src/stdio/CMakeLists.txt | 1 +
libc/src/stdio/generic/CMakeLists.txt | 17 +++++-
libc/src/stdio/generic/iprintf.cpp | 39 ++++++++++++
libc/src/stdio/iprintf.h | 21 +++++++
libc/src/stdio/printf_core/CMakeLists.txt | 74 +++++++++++++++++++++++
libc/test/src/stdio/CMakeLists.txt | 11 ++++
libc/test/src/stdio/iprintf_test.cpp | 33 ++++++++++
8 files changed, 196 insertions(+), 1 deletion(-)
create mode 100644 libc/src/stdio/generic/iprintf.cpp
create mode 100644 libc/src/stdio/iprintf.h
create mode 100644 libc/test/src/stdio/iprintf_test.cpp
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 9a4a0ff9e75a40..e5d90dfa2010fa 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -212,6 +212,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdio.fscanf
libc.src.stdio.vfscanf
libc.src.stdio.printf
+ libc.src.stdio.iprintf
libc.src.stdio.remove
libc.src.stdio.rename
libc.src.stdio.scanf
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index b9bc904471df9a..4456e9cb3ad16b 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -286,6 +286,7 @@ add_stdio_entrypoint_object(fputc)
add_stdio_entrypoint_object(putc)
add_stdio_entrypoint_object(putchar)
add_stdio_entrypoint_object(printf)
+add_stdio_entrypoint_object(iprintf)
add_stdio_entrypoint_object(fprintf)
add_stdio_entrypoint_object(fgetc)
add_stdio_entrypoint_object(fgetc_unlocked)
diff --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt
index bf301a6b0cb3c6..250d0ec58a12fc 100644
--- a/libc/src/stdio/generic/CMakeLists.txt
+++ b/libc/src/stdio/generic/CMakeLists.txt
@@ -366,7 +366,6 @@ add_entrypoint_object(
list(APPEND fprintf_deps
libc.hdr.types.FILE
libc.src.__support.arg_list
- libc.src.stdio.printf_core.vfprintf_internal
)
if(LLVM_LIBC_FULL_BUILD)
@@ -393,6 +392,19 @@ add_entrypoint_object(
../printf.h
DEPENDS
${printf_deps}
+ libc.src.stdio.printf_core.vfprintf_internal
+)
+
+# the printf variant with no floats is called iprintf for some reason
+add_entrypoint_object(
+ iprintf
+ SRCS
+ iprintf.cpp
+ HDRS
+ ../iprintf.h
+ DEPENDS
+ ${printf_deps}
+ libc.src.stdio.printf_core.vfprintf_internal_nofloat
)
add_entrypoint_object(
@@ -403,6 +415,7 @@ add_entrypoint_object(
../vprintf.h
DEPENDS
${printf_deps}
+ libc.src.stdio.printf_core.vfprintf_internal
)
add_entrypoint_object(
@@ -413,6 +426,7 @@ add_entrypoint_object(
../fprintf.h
DEPENDS
${fprintf_deps}
+ libc.src.stdio.printf_core.vfprintf_internal
)
add_entrypoint_object(
@@ -423,6 +437,7 @@ add_entrypoint_object(
../vfprintf.h
DEPENDS
${fprintf_deps}
+ libc.src.stdio.printf_core.vfprintf_internal
)
add_entrypoint_object(
diff --git a/libc/src/stdio/generic/iprintf.cpp b/libc/src/stdio/generic/iprintf.cpp
new file mode 100644
index 00000000000000..5b124d74311144
--- /dev/null
+++ b/libc/src/stdio/generic/iprintf.cpp
@@ -0,0 +1,39 @@
+//===-- Implementation of iprintf -------------------------------*- 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/iprintf.h"
+
+#include "src/__support/File/file.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/printf_core/vfprintf_internal.h"
+
+#include "hdr/types/FILE.h"
+#include <stdarg.h>
+
+#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_DECL {
+
+LLVM_LIBC_FUNCTION(int, iprintf, (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_DECL
diff --git a/libc/src/stdio/iprintf.h b/libc/src/stdio/iprintf.h
new file mode 100644
index 00000000000000..8844c03618da8a
--- /dev/null
+++ b/libc/src/stdio/iprintf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header of iprintf ------------------------*- 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_IPRINTF_H
+#define LLVM_LIBC_SRC_STDIO_IPRINTF_H
+
+#include "hdr/types/FILE.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int iprintf(const char *__restrict format, ...);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDIO_IPRINTF_H
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index 9eaffe2f7ed621..d8489e8dcf1cf7 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -22,6 +22,11 @@ endif()
if(LIBC_CONF_PRINTF_DISABLE_STRERROR)
list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_DISABLE_STRERROR")
endif()
+
+set(printf_config_copts_nofloat ${printf_config_copts})
+list(APPEND printf_config_copts_nofloat "-DLIBC_COPT_PRINTF_DISABLE_FLOAT")
+list(PREPEND printf_config_copts_nofloat "COMPILE_OPTIONS")
+
if(printf_config_copts)
list(PREPEND printf_config_copts "COMPILE_OPTIONS")
endif()
@@ -33,6 +38,14 @@ add_header_library(
${printf_config_copts}
)
+
+add_header_library(
+ printf_config_nofloat
+ HDRS
+ printf_config.h
+ ${printf_config_copts_nofloat}
+)
+
add_header_library(
core_structs
HDRS
@@ -110,6 +123,41 @@ add_object_library(
libc.src.__support.StringUtil.error_to_string
)
+
+add_object_library(
+ converter_nofloat
+ SRCS
+ converter.cpp
+ HDRS
+ converter.h
+ converter_atlas.h
+ converter_utils.h
+ string_converter.h
+ char_converter.h
+ int_converter.h
+ ptr_converter.h
+ write_int_converter.h
+ fixed_converter.h #TODO: Check if this should be disabled when fixed unavail
+ strerror_converter.h
+ DEPENDS
+ .core_structs
+ .printf_config_nofloat
+ .writer
+ libc.src.__support.big_int
+ libc.src.__support.common
+ libc.src.__support.CPP.limits
+ libc.src.__support.CPP.span
+ libc.src.__support.CPP.string_view
+ libc.src.__support.float_to_string
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.integer_to_string
+ libc.src.__support.libc_assert
+ libc.src.__support.uint128
+ libc.src.__support.StringUtil.error_to_string
+)
+
add_object_library(
printf_main
SRCS
@@ -124,6 +172,20 @@ add_object_library(
libc.src.__support.arg_list
)
+add_object_library(
+ printf_main_nofloat
+ SRCS
+ printf_main.cpp
+ HDRS
+ printf_main.h
+ DEPENDS
+ .parser
+ .converter_nofloat
+ .writer
+ .core_structs
+ libc.src.__support.arg_list
+)
+
add_header_library(
vasprintf_internal
HDRS
@@ -154,3 +216,15 @@ add_header_library(
libc.src.stdio.printf_core.writer
${use_system_file}
)
+
+add_header_library(
+ vfprintf_internal_nofloat
+ HDRS
+ vfprintf_internal.h
+ DEPENDS
+ libc.src.__support.File.file
+ libc.src.__support.arg_list
+ libc.src.stdio.printf_core.printf_main_nofloat
+ libc.src.stdio.printf_core.writer
+ ${use_system_file}
+)
diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
index e17f8d8c101a96..a4e166fd7beec9 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -197,6 +197,17 @@ add_libc_test(
libc.src.stdio.printf
)
+add_libc_test(
+ iprintf_test
+ ${hermetic_test_only}
+ SUITE
+ libc_stdio_unittests
+ SRCS
+ iprintf_test.cpp
+ DEPENDS
+ libc.src.stdio.iprintf
+)
+
add_libc_test(
asprintf_test
SUITE
diff --git a/libc/test/src/stdio/iprintf_test.cpp b/libc/test/src/stdio/iprintf_test.cpp
new file mode 100644
index 00000000000000..3be6b9c9edf86e
--- /dev/null
+++ b/libc/test/src/stdio/iprintf_test.cpp
@@ -0,0 +1,33 @@
+//===-- Unittests for iprintf ---------------------------------------------===//
+//
+// 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/iprintf.h"
+
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcIprintfTest, PrintOut) {
+ int written;
+
+ constexpr char simple[] = "A simple string with no conversions.\n";
+ written = LIBC_NAMESPACE::iprintf(simple);
+ EXPECT_EQ(written, static_cast<int>(sizeof(simple) - 1));
+
+ constexpr char numbers[] = "1234567890\n";
+ written = LIBC_NAMESPACE::iprintf("%s", numbers);
+ EXPECT_EQ(written, static_cast<int>(sizeof(numbers) - 1));
+
+ constexpr char format_more[] = "%s and more\n";
+ constexpr char short_numbers[] = "1234";
+ written = LIBC_NAMESPACE::iprintf(format_more, short_numbers);
+ EXPECT_EQ(written,
+ static_cast<int>(sizeof(format_more) + sizeof(short_numbers) - 4));
+
+ constexpr char format_float[] = "%f doesn't work\n";
+ written = LIBC_NAMESPACE::iprintf(format_float, 1.0);
+ EXPECT_EQ(written, static_cast<int>(sizeof(format_float) - 1));
+}
More information about the libc-commits
mailing list