[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