[libc-commits] [libc] [libc] Add strftime_l (PR #127708)

Petr Hosek via libc-commits libc-commits at lists.llvm.org
Tue Feb 18 22:33:32 PST 2025


https://github.com/petrhosek updated https://github.com/llvm/llvm-project/pull/127708

>From 17677eef32dfd1a2ddf455838c85c3dd338f7cff Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Thu, 13 Feb 2025 11:04:34 -0800
Subject: [PATCH 1/3] [libc] Add strftime_l

This is a (no-op) locale version of strftime.
---
 libc/config/baremetal/aarch64/entrypoints.txt |  1 +
 libc/config/baremetal/arm/entrypoints.txt     |  1 +
 libc/config/baremetal/riscv/entrypoints.txt   |  1 +
 libc/include/time.yaml                        | 11 +++++++
 libc/src/time/CMakeLists.txt                  | 11 +++++++
 libc/src/time/strftime.cpp                    |  1 -
 libc/src/time/strftime_l.cpp                  | 33 +++++++++++++++++++
 libc/src/time/strftime_l.h                    | 25 ++++++++++++++
 8 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/time/strftime_l.cpp
 create mode 100644 libc/src/time/strftime_l.h

diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 44c4ab49e5c58..8becbe41c6e14 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -248,6 +248,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.strftime_l
     libc.src.time.timespec_get
 
     # internal entrypoints
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 370b5462fe9e8..99a9b9a645e70 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -248,6 +248,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.strftime_l
     libc.src.time.timespec_get
 
     # internal entrypoints
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 07311a60a17a2..91e4b14a46228 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -244,6 +244,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.strftime_l
     libc.src.time.timespec_get
 
     # internal entrypoints
diff --git a/libc/include/time.yaml b/libc/include/time.yaml
index 37ee824678cda..7bb25dbe85ac4 100644
--- a/libc/include/time.yaml
+++ b/libc/include/time.yaml
@@ -9,6 +9,7 @@ types:
   - type_name: time_t
   - type_name: clock_t
   - type_name: size_t
+  - type_name: locale_t
 enums: []
 objects: []
 functions:
@@ -100,6 +101,16 @@ functions:
       - type: size_t
       - type: const char *__restrict
       - type: const struct tm *__restrict
+  - name: strftime_l
+    standard:
+      - stdc
+    return_type: size_t
+    arguments:
+      - type: char *__restrict
+      - type: size_t
+      - type: const char *__restrict
+      - type: const struct tm *__restrict
+      - type: locale_t
   - name: time
     standard:
       - stdc
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 8332e8ab66f97..868253f4b03b5 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -150,6 +150,17 @@ add_entrypoint_object(
     libc.src.time.strftime_core.strftime_main
 )
 
+add_entrypoint_object(
+  strftime_l
+  SRCS
+    strftime_l.cpp
+  HDRS
+    strftime_l.h
+  DEPENDS
+    libc.hdr.types.size_t
+    libc.hdr.types.struct_tm
+)
+
 add_entrypoint_object(
   time
   SRCS
diff --git a/libc/src/time/strftime.cpp b/libc/src/time/strftime.cpp
index 4b89bf2ea3a70..c19e58fbadf71 100644
--- a/libc/src/time/strftime.cpp
+++ b/libc/src/time/strftime.cpp
@@ -19,7 +19,6 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(size_t, strftime,
                    (char *__restrict buffer, size_t buffsz,
                     const char *__restrict format, const tm *timeptr)) {
-
   printf_core::WriteBuffer wb(buffer, (buffsz > 0 ? buffsz - 1 : 0));
   printf_core::Writer writer(&wb);
   int ret = strftime_core::strftime_main(&writer, format, timeptr);
diff --git a/libc/src/time/strftime_l.cpp b/libc/src/time/strftime_l.cpp
new file mode 100644
index 0000000000000..4203136af4cba
--- /dev/null
+++ b/libc/src/time/strftime_l.cpp
@@ -0,0 +1,33 @@
+//===-- Implementation of strftime_l function -----------------------------===//
+//
+// 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/time/strftime_l.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/struct_tm.h"
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/printf_core/writer.h"
+#include "src/time/strftime_core/strftime_main.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// TODO: Add support for locales.
+LLVM_LIBC_FUNCTION(size_t, strftime_l,
+                   (char *__restrict buffer, size_t count,
+                    const char *__restrict format,
+                    const struct tm *__restrict tp, locale_t)) {
+  printf_core::WriteBuffer wb(buffer, (buffsz > 0 ? buffsz - 1 : 0));
+  printf_core::Writer writer(&wb);
+  int ret = strftime_core::strftime_main(&writer, format, timeptr);
+  if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
+    wb.buff[wb.buff_cur] = '\0';
+  return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/strftime_l.h b/libc/src/time/strftime_l.h
new file mode 100644
index 0000000000000..57a6d4070cd06
--- /dev/null
+++ b/libc/src/time/strftime_l.h
@@ -0,0 +1,25 @@
+//===-- Implementation header for strftime_l --------------------*- 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_TIME_STRFTIME_L_H
+#define LLVM_LIBC_SRC_TIME_STRFTIME_L_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/struct_tm.h"
+#include "include/llvm-libc-types/locale_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t strftime_l(char *__restrict buffer, size_t count,
+                  const char *__restrict format, const struct tm *__restrict tp,
+                  locale_t);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STRING_STRCOLL_L_H

>From 1755498f88926b9eaff33ae06d037a6c41f804cf Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 18 Feb 2025 14:29:52 -0800
Subject: [PATCH 2/3] Fix comment

---
 libc/src/time/strftime_l.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/time/strftime_l.h b/libc/src/time/strftime_l.h
index 57a6d4070cd06..158c4a63986b4 100644
--- a/libc/src/time/strftime_l.h
+++ b/libc/src/time/strftime_l.h
@@ -22,4 +22,4 @@ size_t strftime_l(char *__restrict buffer, size_t count,
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_STRING_STRCOLL_L_H
+#endif // LLVM_LIBC_SRC_TIME_STRFTIME_L_H

>From b99acdff8533d72bbc6e7d35fdb4849a8754698c Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 18 Feb 2025 22:33:06 -0800
Subject: [PATCH 3/3] Address code review feedback

---
 libc/config/baremetal/aarch64/entrypoints.txt | 1 +
 libc/config/baremetal/arm/entrypoints.txt     | 1 +
 libc/config/baremetal/riscv/entrypoints.txt   | 1 +
 libc/config/linux/x86_64/entrypoints.txt      | 1 +
 libc/src/time/CMakeLists.txt                  | 3 +++
 5 files changed, 7 insertions(+)

diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 8becbe41c6e14..2c226ef176c08 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -248,6 +248,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.strftime
     libc.src.time.strftime_l
     libc.src.time.timespec_get
 
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 99a9b9a645e70..6fd1fce3ab245 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -248,6 +248,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.strftime
     libc.src.time.strftime_l
     libc.src.time.timespec_get
 
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 91e4b14a46228..5985c495bdaf2 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -244,6 +244,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.strftime
     libc.src.time.strftime_l
     libc.src.time.timespec_get
 
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index a4f6671a59789..2e3af00ec303d 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1128,6 +1128,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.mktime
     libc.src.time.nanosleep
     libc.src.time.strftime
+    libc.src.time.strftime_l
     libc.src.time.time
     libc.src.time.timespec_get
 
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 868253f4b03b5..3b951df810011 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -157,8 +157,11 @@ add_entrypoint_object(
   HDRS
     strftime_l.h
   DEPENDS
+    libc.hdr.types.locale_t
     libc.hdr.types.size_t
     libc.hdr.types.struct_tm
+    libc.src.stdio.printf_core.writer
+    libc.src.time.strftime_core.strftime_main
 )
 
 add_entrypoint_object(



More information about the libc-commits mailing list