[libc-commits] [clang] [clang-tools-extra] [libc] [libc][c11] implement ctime (PR #107285)
Зишан Мирза via libc-commits
libc-commits at lists.llvm.org
Wed Sep 11 22:00:13 PDT 2024
https://github.com/zimirza updated https://github.com/llvm/llvm-project/pull/107285
>From b982621407a1ab1746a023809aae5c6a2b983679 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Tue, 3 Sep 2024 22:47:30 +0200
Subject: [PATCH 01/55] [libc][c11] implement ctime (#86567)
---
libc/src/time/CMakeLists.txt | 11 ++
libc/src/time/ctime.cpp | 23 ++++
libc/src/time/ctime.h | 21 +++
libc/src/time/time_utils.h | 46 +++++++
libc/test/src/time/ctime_test.cpp | 215 ++++++++++++++++++++++++++++++
5 files changed, 316 insertions(+)
create mode 100644 libc/src/time/ctime.cpp
create mode 100644 libc/src/time/ctime.h
create mode 100644 libc/test/src/time/ctime_test.cpp
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 5680718715974e..befe67677f3ec7 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -36,6 +36,17 @@ add_entrypoint_object(
libc.include.time
)
+add_entrypoint_object(
+ ctime
+ SRCS
+ ctime.cpp
+ HDRS
+ ctime.h
+ DEPENDS
+ .time_utils
+ libc.include.time
+)
+
add_entrypoint_object(
difftime
SRCS
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
new file mode 100644
index 00000000000000..f3181816ad9ab1
--- /dev/null
+++ b/libc/src/time/ctime.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of asctime 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/ctime.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/time/time_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+using LIBC_NAMESPACE::time_utils::TimeConstants;
+
+LLVM_LIBC_FUNCTION(char *, ctime, (const struct tm *timeptr)) {
+ static char buffer[TimeConstants::CTIME_BUFFER_SIZE];
+ return time_utils::ctime(timeptr, buffer, TimeConstants::CTIME_MAX_BYTES);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime.h b/libc/src/time/ctime.h
new file mode 100644
index 00000000000000..ec5530ffb5bc71
--- /dev/null
+++ b/libc/src/time/ctime.h
@@ -0,0 +1,21 @@
+//===-- Implementation header of ctime ------------------------*- 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_CTIME_H
+#define LLVM_LIBC_SRC_TIME_CTIME_H
+
+#include "src/__support/macros/config.h"
+#include <time.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+char *ctime(const struct tm *timeptr);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_TIME_CTIME_H
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 47f55f7d389122..6fa590fefac8d0 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -62,6 +62,9 @@ struct TimeConstants {
static constexpr int ASCTIME_BUFFER_SIZE = 256;
static constexpr int ASCTIME_MAX_BYTES = 26;
+ static constexpr int CTIME_BUFFER_SIZE = 256;
+ static constexpr int CTIME_MAX_BYTES = 26;
+
/* 2000-03-01 (mod 400 year, immediately after feb29 */
static constexpr int64_t SECONDS_UNTIL2000_MARCH_FIRST =
(946684800LL + SECONDS_PER_DAY * (31 + 29));
@@ -145,6 +148,49 @@ LIBC_INLINE char *asctime(const struct tm *timeptr, char *buffer,
return buffer;
}
+LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer,
+ size_t bufferLength) {
+ if (timeptr == nullptr || buffer == nullptr) {
+ invalid_value();
+ return nullptr;
+ }
+ if (timeptr->tm_wday < 0 ||
+ timeptr->tm_wday > (TimeConstants::DAYS_PER_WEEK - 1)) {
+ invalid_value();
+ return nullptr;
+ }
+ if (timeptr->tm_mon < 0 ||
+ timeptr->tm_mon > (TimeConstants::MONTHS_PER_YEAR - 1)) {
+ invalid_value();
+ return nullptr;
+ }
+
+ // TODO(rtenneti): i18n the following strings.
+ static const char *week_days_name[TimeConstants::DAYS_PER_WEEK] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+
+ static const char *months_name[TimeConstants::MONTHS_PER_YEAR] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ // TODO(michaelr): look into removing this call to __builtin_snprintf that may
+ // be emitted as a call to snprintf. Alternatively, look into using our
+ // internal printf machinery.
+ int written_size = __builtin_snprintf(
+ buffer, bufferLength, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ week_days_name[timeptr->tm_wday], months_name[timeptr->tm_mon],
+ timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec,
+ TimeConstants::TIME_YEAR_BASE + timeptr->tm_year);
+ if (written_size < 0)
+ return nullptr;
+ if (static_cast<size_t>(written_size) >= bufferLength) {
+ out_of_range();
+ return nullptr;
+ }
+ return buffer;
+}
+
+
LIBC_INLINE struct tm *gmtime_internal(const time_t *timer, struct tm *result) {
int64_t seconds = *timer;
// Update the tm structure's year, month, day, etc. from seconds.
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
new file mode 100644
index 00000000000000..bbf915188eacee
--- /dev/null
+++ b/libc/test/src/time/ctime_test.cpp
@@ -0,0 +1,215 @@
+//===-- Unittests for ctime ---------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// make check-libc LIBC_TEST_TARGET=call_ctime VERBOSE=1
+#include "src/errno/libc_errno.h"
+#include "src/time/ctime.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/time/TmHelper.h"
+
+static inline char *call_ctime(struct tm *tm_data, int year, int month,
+ int mday, int hour, int min, int sec, int wday,
+ int yday) {
+ LIBC_NAMESPACE::tmhelper::testing::initialize_tm_data(
+ tm_data, year, month, mday, hour, min, sec, wday, yday);
+ return LIBC_NAMESPACE::ctime(tm_data);
+}
+
+TEST(LlvmLibcCtime, Nullptr) {
+ char *result;
+ result = LIBC_NAMESPACE::ctime(nullptr);
+ ASSERT_ERRNO_EQ(EINVAL);
+ ASSERT_STREQ(nullptr, result);
+}
+
+// Weekdays are in the range 0 to 6. Test passing invalid value in wday.
+TEST(LlvmLibcCtime, InvalidWday) {
+ struct tm tm_data;
+
+ // Test with wday = -1.
+ call_ctime(&tm_data,
+ 1970, // year
+ 1, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ -1, // wday
+ 0); // yday
+ ASSERT_ERRNO_EQ(EINVAL);
+
+ // Test with wday = 7.
+ call_ctime(&tm_data,
+ 1970, // year
+ 1, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 7, // wday
+ 0); // yday
+ ASSERT_ERRNO_EQ(EINVAL);
+}
+
+// Months are from January to December. Test passing invalid value in month.
+TEST(LlvmLibcCtime, InvalidMonth) {
+ struct tm tm_data;
+
+ // Test with month = 0.
+ call_ctime(&tm_data,
+ 1970, // year
+ 0, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 4, // wday
+ 0); // yday
+ ASSERT_ERRNO_EQ(EINVAL);
+
+ // Test with month = 13.
+ call_ctime(&tm_data,
+ 1970, // year
+ 13, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 4, // wday
+ 0); // yday
+ ASSERT_ERRNO_EQ(EINVAL);
+}
+
+TEST(LlvmLibcCtime, ValidWeekdays) {
+ struct tm tm_data;
+ char *result;
+ // 1970-01-01 00:00:00.
+ result = call_ctime(&tm_data,
+ 1970, // year
+ 1, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 4, // wday
+ 0); // yday
+ ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
+
+ // 1970-01-03 00:00:00.
+ result = call_ctime(&tm_data,
+ 1970, // year
+ 1, // month
+ 3, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 6, // wday
+ 0); // yday
+ ASSERT_STREQ("Sat Jan 3 00:00:00 1970\n", result);
+
+ // 1970-01-04 00:00:00.
+ result = call_ctime(&tm_data,
+ 1970, // year
+ 1, // month
+ 4, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 0, // wday
+ 0); // yday
+ ASSERT_STREQ("Sun Jan 4 00:00:00 1970\n", result);
+}
+
+TEST(LlvmLibcCtime, ValidMonths) {
+ struct tm tm_data;
+ char *result;
+ // 1970-01-01 00:00:00.
+ result = call_ctime(&tm_data,
+ 1970, // year
+ 1, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 4, // wday
+ 0); // yday
+ ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
+
+ // 1970-02-01 00:00:00.
+ result = call_ctime(&tm_data,
+ 1970, // year
+ 2, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 0, // wday
+ 0); // yday
+ ASSERT_STREQ("Sun Feb 1 00:00:00 1970\n", result);
+
+ // 1970-12-31 23:59:59.
+ result = call_ctime(&tm_data,
+ 1970, // year
+ 12, // month
+ 31, // day
+ 23, // hr
+ 59, // min
+ 59, // sec
+ 4, // wday
+ 0); // yday
+ ASSERT_STREQ("Thu Dec 31 23:59:59 1970\n", result);
+}
+
+TEST(LlvmLibcCtime, EndOf32BitEpochYear) {
+ struct tm tm_data;
+ char *result;
+ // Test for maximum value of a signed 32-bit integer.
+ // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC.
+ result = call_ctime(&tm_data,
+ 2038, // year
+ 1, // month
+ 19, // day
+ 3, // hr
+ 14, // min
+ 7, // sec
+ 2, // wday
+ 7); // yday
+ ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
+}
+
+TEST(LlvmLibcCtime, Max64BitYear) {
+ if (sizeof(time_t) == 4)
+ return;
+ // Mon Jan 1 12:50:50 2170 (200 years from 1970),
+ struct tm tm_data;
+ char *result;
+ result = call_ctime(&tm_data,
+ 2170, // year
+ 1, // month
+ 1, // day
+ 12, // hr
+ 50, // min
+ 50, // sec
+ 1, // wday
+ 50); // yday
+ ASSERT_STREQ("Mon Jan 1 12:50:50 2170\n", result);
+
+ // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year.
+ // This test would cause buffer overflow and thus asctime returns nullptr.
+ result = call_ctime(&tm_data,
+ 2147483647, // year
+ 1, // month
+ 1, // day
+ 12, // hr
+ 50, // min
+ 50, // sec
+ 2, // wday
+ 50); // yday
+ ASSERT_ERRNO_EQ(EOVERFLOW);
+ ASSERT_STREQ(nullptr, result);
+}
>From bbbd2a9ca60d1e492b5f0c7cb909770e6d504703 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 18:51:34 +0200
Subject: [PATCH 02/55] [libc][c11] implement ctime
remove buffer length
---
libc/src/time/time_utils.h | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 6fa590fefac8d0..6b2480bc1c0fb0 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -148,8 +148,7 @@ LIBC_INLINE char *asctime(const struct tm *timeptr, char *buffer,
return buffer;
}
-LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer,
- size_t bufferLength) {
+LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer) {
if (timeptr == nullptr || buffer == nullptr) {
invalid_value();
return nullptr;
@@ -177,13 +176,13 @@ LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer,
// be emitted as a call to snprintf. Alternatively, look into using our
// internal printf machinery.
int written_size = __builtin_snprintf(
- buffer, bufferLength, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ buffer, strlen(buffer), "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
week_days_name[timeptr->tm_wday], months_name[timeptr->tm_mon],
timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec,
TimeConstants::TIME_YEAR_BASE + timeptr->tm_year);
if (written_size < 0)
return nullptr;
- if (static_cast<size_t>(written_size) >= bufferLength) {
+ if (static_cast<size_t>(written_size) >= strlen(buffer)) {
out_of_range();
return nullptr;
}
>From e146ac1516944cad0c2e419dd7868b854fb93778 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 19:11:37 +0200
Subject: [PATCH 03/55] [libc][c11] implement ctime
fix: buffer length
---
libc/src/time/time_utils.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 6b2480bc1c0fb0..2386d149072475 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -176,7 +176,7 @@ LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer) {
// be emitted as a call to snprintf. Alternatively, look into using our
// internal printf machinery.
int written_size = __builtin_snprintf(
- buffer, strlen(buffer), "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ buffer, strlen(buffer)+32, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
week_days_name[timeptr->tm_wday], months_name[timeptr->tm_mon],
timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec,
TimeConstants::TIME_YEAR_BASE + timeptr->tm_year);
>From eb02ef75d5fcec26900d40701c96d0a27abd041c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 19:27:58 +0200
Subject: [PATCH 04/55] [libc][c11] implement ctime
add buffer length
---
libc/src/time/time_utils.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 2386d149072475..c4c8b771f865fc 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -148,7 +148,7 @@ LIBC_INLINE char *asctime(const struct tm *timeptr, char *buffer,
return buffer;
}
-LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer) {
+LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer, size_t buffer_length) {
if (timeptr == nullptr || buffer == nullptr) {
invalid_value();
return nullptr;
@@ -176,13 +176,13 @@ LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer) {
// be emitted as a call to snprintf. Alternatively, look into using our
// internal printf machinery.
int written_size = __builtin_snprintf(
- buffer, strlen(buffer)+32, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ buffer, buffer_length, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
week_days_name[timeptr->tm_wday], months_name[timeptr->tm_mon],
timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec,
TimeConstants::TIME_YEAR_BASE + timeptr->tm_year);
if (written_size < 0)
return nullptr;
- if (static_cast<size_t>(written_size) >= strlen(buffer)) {
+ if (static_cast<size_t>(written_size) >= buffer_length) {
out_of_range();
return nullptr;
}
>From 12adb50dc09d9d500ffad40dc58e2a6d94e7073c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 19:43:41 +0200
Subject: [PATCH 05/55] [libc][c11] implement ctime
fix: ctime implementation
---
libc/src/time/time_utils.h | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index c4c8b771f865fc..4cf32ee64cec11 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -148,11 +148,14 @@ LIBC_INLINE char *asctime(const struct tm *timeptr, char *buffer,
return buffer;
}
-LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer, size_t buffer_length) {
- if (timeptr == nullptr || buffer == nullptr) {
+LIBC_INLINE char *ctime(const time_t *t_ptr, char *buffer,
+ size_t buffer_length) {
+ if (t_ptr == nullptr || buffer == nullptr) {
invalid_value();
return nullptr;
}
+ const struct tm *timeptr;
+ timeptr = localtime(t_ptr);
if (timeptr->tm_wday < 0 ||
timeptr->tm_wday > (TimeConstants::DAYS_PER_WEEK - 1)) {
invalid_value();
@@ -189,7 +192,6 @@ LIBC_INLINE char *ctime(const struct tm *timeptr, char *buffer, size_t buffer_le
return buffer;
}
-
LIBC_INLINE struct tm *gmtime_internal(const time_t *timer, struct tm *result) {
int64_t seconds = *timer;
// Update the tm structure's year, month, day, etc. from seconds.
>From b10a47054c26a047e524a424badde2aeb894483b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 19:55:59 +0200
Subject: [PATCH 06/55] [libc][c11] implement ctime
fix: tests
---
libc/test/src/time/ctime_test.cpp | 46 +++++++++++++++----------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index bbf915188eacee..bcc4fe16f795b2 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -12,12 +12,12 @@
#include "test/UnitTest/Test.h"
#include "test/src/time/TmHelper.h"
-static inline char *call_ctime(struct tm *tm_data, int year, int month,
+static inline char *call_ctime(struct time_t *t, int year, int month,
int mday, int hour, int min, int sec, int wday,
int yday) {
LIBC_NAMESPACE::tmhelper::testing::initialize_tm_data(
- tm_data, year, month, mday, hour, min, sec, wday, yday);
- return LIBC_NAMESPACE::ctime(tm_data);
+ localtime(t), year, month, mday, hour, min, sec, wday, yday);
+ return LIBC_NAMESPACE::ctime(t);
}
TEST(LlvmLibcCtime, Nullptr) {
@@ -29,10 +29,10 @@ TEST(LlvmLibcCtime, Nullptr) {
// Weekdays are in the range 0 to 6. Test passing invalid value in wday.
TEST(LlvmLibcCtime, InvalidWday) {
- struct tm tm_data;
+ struct time_t t;
// Test with wday = -1.
- call_ctime(&tm_data,
+ call_ctime(&t,
1970, // year
1, // month
1, // day
@@ -44,7 +44,7 @@ TEST(LlvmLibcCtime, InvalidWday) {
ASSERT_ERRNO_EQ(EINVAL);
// Test with wday = 7.
- call_ctime(&tm_data,
+ call_ctime(&t,
1970, // year
1, // month
1, // day
@@ -58,10 +58,10 @@ TEST(LlvmLibcCtime, InvalidWday) {
// Months are from January to December. Test passing invalid value in month.
TEST(LlvmLibcCtime, InvalidMonth) {
- struct tm tm_data;
+ struct time_t t;
// Test with month = 0.
- call_ctime(&tm_data,
+ call_ctime(&t,
1970, // year
0, // month
1, // day
@@ -73,7 +73,7 @@ TEST(LlvmLibcCtime, InvalidMonth) {
ASSERT_ERRNO_EQ(EINVAL);
// Test with month = 13.
- call_ctime(&tm_data,
+ call_ctime(&t,
1970, // year
13, // month
1, // day
@@ -86,10 +86,10 @@ TEST(LlvmLibcCtime, InvalidMonth) {
}
TEST(LlvmLibcCtime, ValidWeekdays) {
- struct tm tm_data;
+ struct time_t t;
char *result;
// 1970-01-01 00:00:00.
- result = call_ctime(&tm_data,
+ result = call_ctime(&t,
1970, // year
1, // month
1, // day
@@ -101,7 +101,7 @@ TEST(LlvmLibcCtime, ValidWeekdays) {
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
// 1970-01-03 00:00:00.
- result = call_ctime(&tm_data,
+ result = call_ctime(&t,
1970, // year
1, // month
3, // day
@@ -113,7 +113,7 @@ TEST(LlvmLibcCtime, ValidWeekdays) {
ASSERT_STREQ("Sat Jan 3 00:00:00 1970\n", result);
// 1970-01-04 00:00:00.
- result = call_ctime(&tm_data,
+ result = call_ctime(&t,
1970, // year
1, // month
4, // day
@@ -126,10 +126,10 @@ TEST(LlvmLibcCtime, ValidWeekdays) {
}
TEST(LlvmLibcCtime, ValidMonths) {
- struct tm tm_data;
+ struct time_t t;
char *result;
// 1970-01-01 00:00:00.
- result = call_ctime(&tm_data,
+ result = call_ctime(&t,
1970, // year
1, // month
1, // day
@@ -141,7 +141,7 @@ TEST(LlvmLibcCtime, ValidMonths) {
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
// 1970-02-01 00:00:00.
- result = call_ctime(&tm_data,
+ result = call_ctime(&t,
1970, // year
2, // month
1, // day
@@ -153,7 +153,7 @@ TEST(LlvmLibcCtime, ValidMonths) {
ASSERT_STREQ("Sun Feb 1 00:00:00 1970\n", result);
// 1970-12-31 23:59:59.
- result = call_ctime(&tm_data,
+ result = call_ctime(&t,
1970, // year
12, // month
31, // day
@@ -166,11 +166,11 @@ TEST(LlvmLibcCtime, ValidMonths) {
}
TEST(LlvmLibcCtime, EndOf32BitEpochYear) {
- struct tm tm_data;
+ struct time_t t;
char *result;
// Test for maximum value of a signed 32-bit integer.
// Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC.
- result = call_ctime(&tm_data,
+ result = call_ctime(&t,
2038, // year
1, // month
19, // day
@@ -186,9 +186,9 @@ TEST(LlvmLibcCtime, Max64BitYear) {
if (sizeof(time_t) == 4)
return;
// Mon Jan 1 12:50:50 2170 (200 years from 1970),
- struct tm tm_data;
+ struct time_t t;
char *result;
- result = call_ctime(&tm_data,
+ result = call_ctime(&t,
2170, // year
1, // month
1, // day
@@ -200,8 +200,8 @@ TEST(LlvmLibcCtime, Max64BitYear) {
ASSERT_STREQ("Mon Jan 1 12:50:50 2170\n", result);
// Test for Tue Jan 1 12:50:50 in 2,147,483,647th year.
- // This test would cause buffer overflow and thus asctime returns nullptr.
- result = call_ctime(&tm_data,
+ // This test would cause buffer overflow and thus ctime returns nullptr.
+ result = call_ctime(&t,
2147483647, // year
1, // month
1, // day
>From bd482baa9922c0aeb34c617fcbc943fb6c811bb5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 20:01:34 +0200
Subject: [PATCH 07/55] [libc][ctime] ctime implementation
fix: function declaration
---
libc/src/time/ctime.cpp | 6 +++---
libc/src/time/ctime.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index f3181816ad9ab1..5997018689c802 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of asctime function --------------------------------===//
+//===-- Implementation of ctime function --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -15,9 +15,9 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
-LLVM_LIBC_FUNCTION(char *, ctime, (const struct tm *timeptr)) {
+LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t)) {
static char buffer[TimeConstants::CTIME_BUFFER_SIZE];
- return time_utils::ctime(timeptr, buffer, TimeConstants::CTIME_MAX_BYTES);
+ return time_utils::ctime(&t, buffer, TimeConstants::CTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime.h b/libc/src/time/ctime.h
index ec5530ffb5bc71..b4e31ae852fe76 100644
--- a/libc/src/time/ctime.h
+++ b/libc/src/time/ctime.h
@@ -14,7 +14,7 @@
namespace LIBC_NAMESPACE_DECL {
-char *ctime(const struct tm *timeptr);
+char *ctime(const time_t *t);
} // namespace LIBC_NAMESPACE_DECL
>From a1d86d2430dc46bd8154307a6a63bcc9a632de07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 20:09:03 +0200
Subject: [PATCH 08/55] [libc][c11] ctime implementation
format code with `clang-format`
---
libc/test/src/time/ctime_test.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index bcc4fe16f795b2..19daa88ddeb4d6 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -12,9 +12,8 @@
#include "test/UnitTest/Test.h"
#include "test/src/time/TmHelper.h"
-static inline char *call_ctime(struct time_t *t, int year, int month,
- int mday, int hour, int min, int sec, int wday,
- int yday) {
+static inline char *call_ctime(struct time_t *t, int year, int month, int mday,
+ int hour, int min, int sec, int wday, int yday) {
LIBC_NAMESPACE::tmhelper::testing::initialize_tm_data(
localtime(t), year, month, mday, hour, min, sec, wday, yday);
return LIBC_NAMESPACE::ctime(t);
>From de83e31dc35dde34ed920444d63facb4d1bdc7dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 20:23:15 +0200
Subject: [PATCH 09/55] [libc][c11] implement ctime
implement `ctime_r`
---
libc/src/time/ctime.cpp | 2 +-
libc/src/time/ctime.h | 2 +-
libc/src/time/ctime_r.cpp | 22 +++++++++++
libc/src/time/ctime_r.h | 21 ++++++++++
libc/test/src/time/ctime_r_test.cpp | 60 +++++++++++++++++++++++++++++
libc/test/src/time/ctime_test.cpp | 2 +-
6 files changed, 106 insertions(+), 3 deletions(-)
create mode 100644 libc/src/time/ctime_r.cpp
create mode 100644 libc/src/time/ctime_r.h
create mode 100644 libc/test/src/time/ctime_r_test.cpp
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 5997018689c802..7089d5f7ff0c38 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of ctime function --------------------------------===//
+//===-- Implementation of ctime function ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/time/ctime.h b/libc/src/time/ctime.h
index b4e31ae852fe76..4afc8fddc8c44a 100644
--- a/libc/src/time/ctime.h
+++ b/libc/src/time/ctime.h
@@ -1,4 +1,4 @@
-//===-- Implementation header of ctime ------------------------*- C++ -*-===//
+//===-- Implementation header of ctime --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
new file mode 100644
index 00000000000000..c25217d8d22cfc
--- /dev/null
+++ b/libc/src/time/ctime_r.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of ctime_r 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/ctime_r.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/time/time_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+using LIBC_NAMESPACE::time_utils::TimeConstants;
+
+LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t, char *buffer)) {
+ return time_utils::ctime(t, buffer, TimeConstants::CTIME_MAX_BYTES);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime_r.h b/libc/src/time/ctime_r.h
new file mode 100644
index 00000000000000..688646c8d12674
--- /dev/null
+++ b/libc/src/time/ctime_r.h
@@ -0,0 +1,21 @@
+//===-- Implementation header of ctime_r ------------------------*- 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_ASCTIME_R_H
+#define LLVM_LIBC_SRC_TIME_ASCTIME_R_H
+
+#include "src/__support/macros/config.h"
+#include <time.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+char *ctime_r(const time_t *t, char *buffer);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_TIME_CTIME_R_H
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
new file mode 100644
index 00000000000000..ab742368f02cc3
--- /dev/null
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -0,0 +1,60 @@
+//===-- Unittests for ctime_r ---------------------------------------------===//
+//
+// 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/errno/libc_errno.h"
+#include "src/time/ctime_r.h"
+#include "src/time/time_utils.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/time/TmHelper.h"
+
+using LIBC_NAMESPACE::time_utils::TimeConstants;
+
+static inline char *call_ctime_r(time_t *t, int year, int month, int mday,
+ int hour, int min, int sec, int wday, int yday,
+ char *buffer) {
+ LIBC_NAMESPACE::tmhelper::testing::initialize_tm_data(
+ localtime(t), year, month, mday, hour, min, sec, wday, yday);
+ return LIBC_NAMESPACE::ctime_r(t, buffer);
+}
+
+// ctime and ctime_r share the same code and thus didn't repeat all the
+// tests from ctime. Added couple of validation tests.
+TEST(LlvmLibcCtimeR, Nullptr) {
+ char *result;
+ result = LIBC_NAMESPACE::ctime_r(nullptr, nullptr);
+ ASSERT_ERRNO_EQ(EINVAL);
+ ASSERT_STREQ(nullptr, result);
+
+ char buffer[TimeConstants::CTIME_BUFFER_SIZE];
+ result = LIBC_NAMESPACE::ctime_r(nullptr, buffer);
+ ASSERT_ERRNO_EQ(EINVAL);
+ ASSERT_STREQ(nullptr, result);
+
+ time_t t;
+ result = LIBC_NAMESPACE::ctime_r(&tm_data, nullptr);
+ ASSERT_ERRNO_EQ(EINVAL);
+ ASSERT_STREQ(nullptr, result);
+}
+
+TEST(LlvmLibcCtimeR, ValidDate) {
+ char buffer[TimeConstants::CTIME_BUFFER_SIZE];
+ struct time_t t;
+ char *result;
+ // 1970-01-01 00:00:00. Test with a valid buffer size.
+ result = call_ctime_r(&t,
+ 1970, // year
+ 1, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 4, // wday
+ 0, // yday
+ buffer);
+ ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
+}
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index 19daa88ddeb4d6..6d1282e181baba 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -1,4 +1,4 @@
-//===-- Unittests for ctime ---------------------------------------------===//
+//===-- Unittests for ctime -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
>From b7d6c7398ee6dd7f9de72819577a14d224c803d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 20:25:49 +0200
Subject: [PATCH 10/55] [libc][c11] implement ctime
fix: `ctime_r` header file
---
libc/src/time/ctime_r.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/time/ctime_r.h b/libc/src/time/ctime_r.h
index 688646c8d12674..93acad13c28e44 100644
--- a/libc/src/time/ctime_r.h
+++ b/libc/src/time/ctime_r.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_TIME_ASCTIME_R_H
-#define LLVM_LIBC_SRC_TIME_ASCTIME_R_H
+#ifndef LLVM_LIBC_SRC_TIME_CTIME_R_H
+#define LLVM_LIBC_SRC_TIME_CTIME_R_H
#include "src/__support/macros/config.h"
#include <time.h>
>From 948786a3f51c5619c58a4c307ac17411a1ef82a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 4 Sep 2024 20:27:31 +0200
Subject: [PATCH 11/55] [libc][c11] implement ctime
add `ctime_r` to `cmake`
---
libc/src/time/CMakeLists.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index befe67677f3ec7..1605a6b897c14b 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -47,6 +47,17 @@ add_entrypoint_object(
libc.include.time
)
+add_entrypoint_object(
+ ctime_r
+ SRCS
+ ctime_r.cpp
+ HDRS
+ ctime_r.h
+ DEPENDS
+ .time_utils
+ libc.include.time
+)
+
add_entrypoint_object(
difftime
SRCS
>From 574583a7f8db33516bbee82414e71943d7588e59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 13:02:46 +0200
Subject: [PATCH 12/55] [libc][c11] implement ctime
add `ctime` and `ctime_r` to build system
---
libc/config/linux/x86_64/entrypoints.txt | 2 ++
libc/newhdrgen/yaml/time.yaml | 13 +++++++++++++
libc/spec/stdc.td | 13 +++++++++++++
3 files changed, 28 insertions(+)
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3fd88fc0020e55..2a38db5bcdad8c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1003,6 +1003,8 @@ if(LLVM_LIBC_FULL_BUILD)
# time.h entrypoints
libc.src.time.asctime
libc.src.time.asctime_r
+ libc.src.time.ctime
+ libc.src.time.ctime_r
libc.src.time.clock
libc.src.time.clock_gettime
libc.src.time.difftime
diff --git a/libc/newhdrgen/yaml/time.yaml b/libc/newhdrgen/yaml/time.yaml
index d2344671831c7a..69b40bef3160dd 100644
--- a/libc/newhdrgen/yaml/time.yaml
+++ b/libc/newhdrgen/yaml/time.yaml
@@ -24,6 +24,19 @@ functions:
arguments:
- type: struct tm *
- type: char *
+ - name: ctime
+ standard:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: const time_t *
+ - name: ctime_r
+ standard:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: const time_t *
+ - type: char *
- name: clock
standard:
- stdc
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index a4ae3e1ff7d9c6..f5ae14ab12d705 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -1600,6 +1600,19 @@ def StdC : StandardSpec<"stdc"> {
ArgSpec<CharPtr>,
]
>,
+ FunctionSpec<
+ "ctime",
+ RetValSpec<CharPtr>,
+ [ArgSpec<StructTmPtr>]
+ >,
+ FunctionSpec<
+ "ctime_r",
+ RetValSpec<CharPtr>,
+ [
+ ArgSpec<StructTmPtr>,
+ ArgSpec<CharPtr>,
+ ]
+ >,
FunctionSpec<
"clock",
RetValSpec<ClockT>,
>From 7743993d6017e94a4c138008d3f13ff0048bad24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 13:04:07 +0200
Subject: [PATCH 13/55] [libc][c11] implement ctime
refactor `ctime` and `ctime_r` to use `asctime`
---
libc/src/time/ctime.cpp | 4 ++--
libc/src/time/ctime.h | 2 +-
libc/src/time/time_utils.h | 44 --------------------------------------
3 files changed, 3 insertions(+), 47 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 7089d5f7ff0c38..ceea1e01bec0f8 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -15,9 +15,9 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
-LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t)) {
+LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
static char buffer[TimeConstants::CTIME_BUFFER_SIZE];
- return time_utils::ctime(&t, buffer, TimeConstants::CTIME_MAX_BYTES);
+ return time_utils::asctime(localtime(&t_ptr), buffer, TimeConstants::CTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime.h b/libc/src/time/ctime.h
index 4afc8fddc8c44a..d5be450d03f231 100644
--- a/libc/src/time/ctime.h
+++ b/libc/src/time/ctime.h
@@ -14,7 +14,7 @@
namespace LIBC_NAMESPACE_DECL {
-char *ctime(const time_t *t);
+char *ctime(const time_t *t_ptr);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 4cf32ee64cec11..688fac28fd2293 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -148,50 +148,6 @@ LIBC_INLINE char *asctime(const struct tm *timeptr, char *buffer,
return buffer;
}
-LIBC_INLINE char *ctime(const time_t *t_ptr, char *buffer,
- size_t buffer_length) {
- if (t_ptr == nullptr || buffer == nullptr) {
- invalid_value();
- return nullptr;
- }
- const struct tm *timeptr;
- timeptr = localtime(t_ptr);
- if (timeptr->tm_wday < 0 ||
- timeptr->tm_wday > (TimeConstants::DAYS_PER_WEEK - 1)) {
- invalid_value();
- return nullptr;
- }
- if (timeptr->tm_mon < 0 ||
- timeptr->tm_mon > (TimeConstants::MONTHS_PER_YEAR - 1)) {
- invalid_value();
- return nullptr;
- }
-
- // TODO(rtenneti): i18n the following strings.
- static const char *week_days_name[TimeConstants::DAYS_PER_WEEK] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
-
- static const char *months_name[TimeConstants::MONTHS_PER_YEAR] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
- // TODO(michaelr): look into removing this call to __builtin_snprintf that may
- // be emitted as a call to snprintf. Alternatively, look into using our
- // internal printf machinery.
- int written_size = __builtin_snprintf(
- buffer, buffer_length, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
- week_days_name[timeptr->tm_wday], months_name[timeptr->tm_mon],
- timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec,
- TimeConstants::TIME_YEAR_BASE + timeptr->tm_year);
- if (written_size < 0)
- return nullptr;
- if (static_cast<size_t>(written_size) >= buffer_length) {
- out_of_range();
- return nullptr;
- }
- return buffer;
-}
-
LIBC_INLINE struct tm *gmtime_internal(const time_t *timer, struct tm *result) {
int64_t seconds = *timer;
// Update the tm structure's year, month, day, etc. from seconds.
>From 2db41fce94abf0c600a274cd7f66161656f92539 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 13:10:02 +0200
Subject: [PATCH 14/55] [libc][c11] implement ctime
fix: `ctime_r`
---
libc/src/time/ctime.cpp | 2 +-
libc/src/time/ctime_r.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index ceea1e01bec0f8..d4bcc6a5bc014e 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -17,7 +17,7 @@ using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
static char buffer[TimeConstants::CTIME_BUFFER_SIZE];
- return time_utils::asctime(localtime(&t_ptr), buffer, TimeConstants::CTIME_MAX_BYTES);
+ return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::CTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index c25217d8d22cfc..b046b04a2e333b 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -15,8 +15,8 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
-LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t, char *buffer)) {
- return time_utils::ctime(t, buffer, TimeConstants::CTIME_MAX_BYTES);
+LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
+ return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::CTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
>From 1fd0113bc57e004de03e7a637d5d5a14871b7ef8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 13:14:14 +0200
Subject: [PATCH 15/55] [libc][c11] implement ctime
add `ctime` and `ctime_r` to `aarch64` and `riscv` architecture
---
libc/config/linux/aarch64/entrypoints.txt | 2 ++
libc/config/linux/riscv/entrypoints.txt | 2 ++
2 files changed, 4 insertions(+)
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 60aa7f5ccb319a..64fbe1a250c0ba 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -948,6 +948,8 @@ if(LLVM_LIBC_FULL_BUILD)
# time.h entrypoints
libc.src.time.asctime
libc.src.time.asctime_r
+ libc.src.time.ctime
+ libc.src.time.ctime_r
libc.src.time.clock
libc.src.time.clock_gettime
libc.src.time.difftime
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 9a2746dcb86f87..ff3d821c664c5b 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -883,6 +883,8 @@ if(LLVM_LIBC_FULL_BUILD)
# time.h entrypoints
libc.src.time.asctime
libc.src.time.asctime_r
+ libc.src.time.ctime
+ libc.src.time.ctime_r
libc.src.time.clock
libc.src.time.clock_gettime
libc.src.time.difftime
>From 2f1a873fe1edfdb169839b7cf78d1d04365d8d83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 14:04:59 +0200
Subject: [PATCH 16/55] [libc][c11] implement ctime
add `ctime` and `ctime_r` to more architectures
---
libc/config/baremetal/arm/entrypoints.txt | 2 ++
libc/config/baremetal/riscv/entrypoints.txt | 2 ++
2 files changed, 4 insertions(+)
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index af9a8bc9925441..68030f7f1775b5 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -203,6 +203,8 @@ set(TARGET_LIBC_ENTRYPOINTS
# time.h entrypoints
libc.src.time.asctime
libc.src.time.asctime_r
+ libc.src.time.ctime
+ libc.src.time.ctime_r
libc.src.time.difftime
libc.src.time.gmtime
libc.src.time.gmtime_r
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 6ebe2e4a29025f..5894b591072ef0 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -199,6 +199,8 @@ set(TARGET_LIBC_ENTRYPOINTS
# time.h entrypoints
libc.src.time.asctime
libc.src.time.asctime_r
+ libc.src.time.ctime
+ libc.src.time.ctime_r
libc.src.time.difftime
libc.src.time.gmtime
libc.src.time.gmtime_r
>From cd65c212e4d109b8670f14c9340f4dc63994e15f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 14:06:10 +0200
Subject: [PATCH 17/55] [libc][c11] implement ctime
- add symbols for `ctime` and `ctime_r`
- add `ctime` and `ctime_r` to clang formatted files list
- add `ctime` to env32-c test
---
clang/docs/tools/clang-formatted-files.txt | 4 ++++
clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc | 2 ++
clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc | 3 +++
clang/test/Analysis/cert/env34-c.c | 1 +
4 files changed, 10 insertions(+)
diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt
index fc07357986d989..2261a726235c1b 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -3062,6 +3062,10 @@ libc/src/time/asctime.cpp
libc/src/time/asctime.h
libc/src/time/asctime_r.cpp
libc/src/time/asctime_r.h
+libc/src/time/ctime.cpp
+libc/src/time/ctime.h
+libc/src/time/ctime_r.cpp
+libc/src/time/ctime_r.h
libc/src/time/gmtime.cpp
libc/src/time/gmtime.h
libc/src/time/gmtime_r.cpp
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
index 463ce921f0672f..849aad0b227da6 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
@@ -220,6 +220,8 @@ SYMBOL(and, None, <iso646.h>)
SYMBOL(and_eq, None, <iso646.h>)
SYMBOL(asctime, None, <time.h>)
SYMBOL(asctime_s, None, <time.h>)
+SYMBOL(ctime, None, <time.h>)
+SYMBOL(ctime_s, None, <time.h>)
SYMBOL(asin, None, <math.h>)
SYMBOL(asinf, None, <math.h>)
SYMBOL(asinh, None, <math.h>)
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
index b46bd2e4d7a4b5..7f0e32b6233e9c 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -617,6 +617,9 @@ SYMBOL(as_writable_bytes, std::, <span>)
SYMBOL(asctime, std::, <ctime>)
SYMBOL(asctime, None, <ctime>)
SYMBOL(asctime, None, <time.h>)
+SYMBOL(ctime, std::, <ctime>)
+SYMBOL(ctime, None, <ctime>)
+SYMBOL(ctime, None, <time.h>)
SYMBOL(asin, std::, <cmath>)
SYMBOL(asin, None, <cmath>)
SYMBOL(asin, None, <math.h>)
diff --git a/clang/test/Analysis/cert/env34-c.c b/clang/test/Analysis/cert/env34-c.c
index d307f0d8f4bb01..79facfe547fa12 100644
--- a/clang/test/Analysis/cert/env34-c.c
+++ b/clang/test/Analysis/cert/env34-c.c
@@ -16,6 +16,7 @@ lconv *localeconv(void);
typedef struct {
} tm;
char *asctime(const tm *timeptr);
+char *ctime(const time_t *timeptr);
int strcmp(const char*, const char*);
extern void foo(char *e);
>From 207e1e0d49c54ecef2a80d8d95659cdd7ef68ca4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 14:34:17 +0200
Subject: [PATCH 18/55] [libc][c11] implement ctime
add header for `time_t`
---
clang/test/Analysis/cert/env34-c.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/test/Analysis/cert/env34-c.c b/clang/test/Analysis/cert/env34-c.c
index 79facfe547fa12..618c089624675e 100644
--- a/clang/test/Analysis/cert/env34-c.c
+++ b/clang/test/Analysis/cert/env34-c.c
@@ -3,6 +3,7 @@
// RUN: -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true \
// RUN: -analyzer-output=text -verify -Wno-unused %s
+#include <time.h>
#include "../Inputs/system-header-simulator.h"
char *getenv(const char *name);
char *setlocale(int category, const char *locale);
>From 925a6a6be58bc75493ecfd8da2e94e1423cf7c6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 14:58:51 +0200
Subject: [PATCH 19/55] [libc][c11] implement ctime
removed `ctime` from analysis test
---
clang/test/Analysis/cert/env34-c.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/clang/test/Analysis/cert/env34-c.c b/clang/test/Analysis/cert/env34-c.c
index 618c089624675e..d307f0d8f4bb01 100644
--- a/clang/test/Analysis/cert/env34-c.c
+++ b/clang/test/Analysis/cert/env34-c.c
@@ -3,7 +3,6 @@
// RUN: -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true \
// RUN: -analyzer-output=text -verify -Wno-unused %s
-#include <time.h>
#include "../Inputs/system-header-simulator.h"
char *getenv(const char *name);
char *setlocale(int category, const char *locale);
@@ -17,7 +16,6 @@ lconv *localeconv(void);
typedef struct {
} tm;
char *asctime(const tm *timeptr);
-char *ctime(const time_t *timeptr);
int strcmp(const char*, const char*);
extern void foo(char *e);
>From 82ab5543f3895c15085605f8b6c877c87c058b40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 16:13:43 +0200
Subject: [PATCH 20/55] [libc][c11] implement ctime
fix: `time_t` definition in `stdc.td`
---
libc/spec/stdc.td | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index f5ae14ab12d705..a8d319d6f8380a 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -3,6 +3,8 @@ def StdC : StandardSpec<"stdc"> {
NamedType StructTmType = NamedType<"struct tm">;
PtrType StructTmPtr = PtrType<StructTmType>;
PtrType TimeTTypePtr = PtrType<TimeTType>;
+ NamedType StructTimeTType = NamedType<"time_t">;
+ PtrType StructTimeTPtr = PtrType<StructTimeTType>;
NamedType ClockT = NamedType<"clock_t">;
NamedType LocaleT = NamedType<"locale_t">;
@@ -1603,13 +1605,13 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<
"ctime",
RetValSpec<CharPtr>,
- [ArgSpec<StructTmPtr>]
+ [ArgSpec<StructTimeTPtr>]
>,
FunctionSpec<
"ctime_r",
RetValSpec<CharPtr>,
[
- ArgSpec<StructTmPtr>,
+ ArgSpec<StructTimeTPtr>,
ArgSpec<CharPtr>,
]
>,
>From 6fa3bc0bf292486b38c4365445e136a3afad26ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 16:49:58 +0200
Subject: [PATCH 21/55] [libc][c11] implement ctime
fix: removed `ctime_s`
---
clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
index 849aad0b227da6..b1f7dc286429cd 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
@@ -221,7 +221,6 @@ SYMBOL(and_eq, None, <iso646.h>)
SYMBOL(asctime, None, <time.h>)
SYMBOL(asctime_s, None, <time.h>)
SYMBOL(ctime, None, <time.h>)
-SYMBOL(ctime_s, None, <time.h>)
SYMBOL(asin, None, <math.h>)
SYMBOL(asinf, None, <math.h>)
SYMBOL(asinh, None, <math.h>)
>From a16d1a965ea0a9642b135a2bd09252955402b3ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 16:51:08 +0200
Subject: [PATCH 22/55] [libc][c11] implement ctime
add `ctime` and `ctime_r` to unsafe functions check
---
clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index ea7eaa0b0ff811..a23f7ea87abe10 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -42,7 +42,7 @@ static StringRef getReplacementFor(StringRef FunctionName,
// Try to find a better replacement from Annex K first.
StringRef AnnexKReplacementFunction =
StringSwitch<StringRef>(FunctionName)
- .Cases("asctime", "asctime_r", "asctime_s")
+ .Cases("asctime", "asctime_r", "asctime_s", "ctime", "ctime_r")
.Case("gets", "gets_s")
.Default({});
if (!AnnexKReplacementFunction.empty())
>From f41a8ed581ac5a56fdb5e5360d99498850c77de6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 20:19:06 +0200
Subject: [PATCH 23/55] [libc][c11] implement ctime
fix: tests
---
libc/test/src/time/ctime_test.cpp | 194 ++----------------------------
1 file changed, 8 insertions(+), 186 deletions(-)
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index 6d1282e181baba..c55fdb1b614aeb 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -12,10 +12,7 @@
#include "test/UnitTest/Test.h"
#include "test/src/time/TmHelper.h"
-static inline char *call_ctime(struct time_t *t, int year, int month, int mday,
- int hour, int min, int sec, int wday, int yday) {
- LIBC_NAMESPACE::tmhelper::testing::initialize_tm_data(
- localtime(t), year, month, mday, hour, min, sec, wday, yday);
+static inline char *call_ctime(struct time_t *t) {
return LIBC_NAMESPACE::ctime(t);
}
@@ -26,189 +23,14 @@ TEST(LlvmLibcCtime, Nullptr) {
ASSERT_STREQ(nullptr, result);
}
-// Weekdays are in the range 0 to 6. Test passing invalid value in wday.
-TEST(LlvmLibcCtime, InvalidWday) {
- struct time_t t;
-
- // Test with wday = -1.
- call_ctime(&t,
- 1970, // year
- 1, // month
- 1, // day
- 0, // hr
- 0, // min
- 0, // sec
- -1, // wday
- 0); // yday
- ASSERT_ERRNO_EQ(EINVAL);
-
- // Test with wday = 7.
- call_ctime(&t,
- 1970, // year
- 1, // month
- 1, // day
- 0, // hr
- 0, // min
- 0, // sec
- 7, // wday
- 0); // yday
- ASSERT_ERRNO_EQ(EINVAL);
-}
-
-// Months are from January to December. Test passing invalid value in month.
-TEST(LlvmLibcCtime, InvalidMonth) {
- struct time_t t;
-
- // Test with month = 0.
- call_ctime(&t,
- 1970, // year
- 0, // month
- 1, // day
- 0, // hr
- 0, // min
- 0, // sec
- 4, // wday
- 0); // yday
- ASSERT_ERRNO_EQ(EINVAL);
-
- // Test with month = 13.
- call_ctime(&t,
- 1970, // year
- 13, // month
- 1, // day
- 0, // hr
- 0, // min
- 0, // sec
- 4, // wday
- 0); // yday
- ASSERT_ERRNO_EQ(EINVAL);
-}
-
-TEST(LlvmLibcCtime, ValidWeekdays) {
- struct time_t t;
- char *result;
- // 1970-01-01 00:00:00.
- result = call_ctime(&t,
- 1970, // year
- 1, // month
- 1, // day
- 0, // hr
- 0, // min
- 0, // sec
- 4, // wday
- 0); // yday
+TEST(LlvmLibcCtime, ValidUnixTimestamp0) {
+ struct time_t t = 0;
+ char* result = call_ctime(&t);
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
-
- // 1970-01-03 00:00:00.
- result = call_ctime(&t,
- 1970, // year
- 1, // month
- 3, // day
- 0, // hr
- 0, // min
- 0, // sec
- 6, // wday
- 0); // yday
- ASSERT_STREQ("Sat Jan 3 00:00:00 1970\n", result);
-
- // 1970-01-04 00:00:00.
- result = call_ctime(&t,
- 1970, // year
- 1, // month
- 4, // day
- 0, // hr
- 0, // min
- 0, // sec
- 0, // wday
- 0); // yday
- ASSERT_STREQ("Sun Jan 4 00:00:00 1970\n", result);
-}
-
-TEST(LlvmLibcCtime, ValidMonths) {
- struct time_t t;
- char *result;
- // 1970-01-01 00:00:00.
- result = call_ctime(&t,
- 1970, // year
- 1, // month
- 1, // day
- 0, // hr
- 0, // min
- 0, // sec
- 4, // wday
- 0); // yday
- ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
-
- // 1970-02-01 00:00:00.
- result = call_ctime(&t,
- 1970, // year
- 2, // month
- 1, // day
- 0, // hr
- 0, // min
- 0, // sec
- 0, // wday
- 0); // yday
- ASSERT_STREQ("Sun Feb 1 00:00:00 1970\n", result);
-
- // 1970-12-31 23:59:59.
- result = call_ctime(&t,
- 1970, // year
- 12, // month
- 31, // day
- 23, // hr
- 59, // min
- 59, // sec
- 4, // wday
- 0); // yday
- ASSERT_STREQ("Thu Dec 31 23:59:59 1970\n", result);
}
-TEST(LlvmLibcCtime, EndOf32BitEpochYear) {
- struct time_t t;
- char *result;
- // Test for maximum value of a signed 32-bit integer.
- // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC.
- result = call_ctime(&t,
- 2038, // year
- 1, // month
- 19, // day
- 3, // hr
- 14, // min
- 7, // sec
- 2, // wday
- 7); // yday
- ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
-}
-
-TEST(LlvmLibcCtime, Max64BitYear) {
- if (sizeof(time_t) == 4)
- return;
- // Mon Jan 1 12:50:50 2170 (200 years from 1970),
- struct time_t t;
- char *result;
- result = call_ctime(&t,
- 2170, // year
- 1, // month
- 1, // day
- 12, // hr
- 50, // min
- 50, // sec
- 1, // wday
- 50); // yday
- ASSERT_STREQ("Mon Jan 1 12:50:50 2170\n", result);
-
- // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year.
- // This test would cause buffer overflow and thus ctime returns nullptr.
- result = call_ctime(&t,
- 2147483647, // year
- 1, // month
- 1, // day
- 12, // hr
- 50, // min
- 50, // sec
- 2, // wday
- 50); // yday
- ASSERT_ERRNO_EQ(EOVERFLOW);
- ASSERT_STREQ(nullptr, result);
+TEST(LlvmLibcCtime, ValidUnixTimestamp32Int) {
+ struct time_t t = 2147483647;
+ char* result = call_ctime(&t);
+ ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
}
>From cf3afc2770496d8e76a617add8b86c39195763d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 20:19:43 +0200
Subject: [PATCH 24/55] [libc][c11] implement ctime
use asctime constants and remove ctime constants
---
libc/src/time/ctime.cpp | 10 +++++-----
libc/src/time/ctime.h | 1 -
libc/src/time/ctime_r.cpp | 2 +-
libc/src/time/time_utils.h | 3 ---
4 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index d4bcc6a5bc014e..dffebc20f47a58 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#include "src/time/ctime.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/time/time_utils.h"
+#include "ctime.h"
+#include "../__support/common.h"
+#include "../__support/macros/config.h"
+#include "time_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -17,7 +17,7 @@ using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
static char buffer[TimeConstants::CTIME_BUFFER_SIZE];
- return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::CTIME_MAX_BYTES);
+ return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime.h b/libc/src/time/ctime.h
index d5be450d03f231..6e9f5fa5d1382a 100644
--- a/libc/src/time/ctime.h
+++ b/libc/src/time/ctime.h
@@ -10,7 +10,6 @@
#define LLVM_LIBC_SRC_TIME_CTIME_H
#include "src/__support/macros/config.h"
-#include <time.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index b046b04a2e333b..2fb7c814a822cc 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
- return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::CTIME_MAX_BYTES);
+ return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 688fac28fd2293..47f55f7d389122 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -62,9 +62,6 @@ struct TimeConstants {
static constexpr int ASCTIME_BUFFER_SIZE = 256;
static constexpr int ASCTIME_MAX_BYTES = 26;
- static constexpr int CTIME_BUFFER_SIZE = 256;
- static constexpr int CTIME_MAX_BYTES = 26;
-
/* 2000-03-01 (mod 400 year, immediately after feb29 */
static constexpr int64_t SECONDS_UNTIL2000_MARCH_FIRST =
(946684800LL + SECONDS_PER_DAY * (31 + 29));
>From 2ff2fa15e8ce647a5f2c5089e52184943ffd6c0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 20:23:33 +0200
Subject: [PATCH 25/55] [libc][c11] implement ctime
use `TimeTTypePtr` and remove `StructTimeTPtr`
---
libc/spec/stdc.td | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index a8d319d6f8380a..c7b697d438a89e 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -3,8 +3,6 @@ def StdC : StandardSpec<"stdc"> {
NamedType StructTmType = NamedType<"struct tm">;
PtrType StructTmPtr = PtrType<StructTmType>;
PtrType TimeTTypePtr = PtrType<TimeTType>;
- NamedType StructTimeTType = NamedType<"time_t">;
- PtrType StructTimeTPtr = PtrType<StructTimeTType>;
NamedType ClockT = NamedType<"clock_t">;
NamedType LocaleT = NamedType<"locale_t">;
@@ -1605,13 +1603,13 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<
"ctime",
RetValSpec<CharPtr>,
- [ArgSpec<StructTimeTPtr>]
+ [ArgSpec<TimeTTypePtr>]
>,
FunctionSpec<
"ctime_r",
RetValSpec<CharPtr>,
[
- ArgSpec<StructTimeTPtr>,
+ ArgSpec<TimeTTypePtr>,
ArgSpec<CharPtr>,
]
>,
>From 677775d55044af0c67d766d6e6348b71ef33efcd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 20:31:35 +0200
Subject: [PATCH 26/55] [libc][c11] implement ctime
remove `ctime` and `ctime_r` from `clang-tidy`
this will be done in https://github.com/llvm/llvm-project/issues/107445
---
clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index a23f7ea87abe10..3d326c5a3b5743 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -42,7 +42,7 @@ static StringRef getReplacementFor(StringRef FunctionName,
// Try to find a better replacement from Annex K first.
StringRef AnnexKReplacementFunction =
StringSwitch<StringRef>(FunctionName)
- .Cases("asctime", "asctime_r", "asctime_s", "ctime", "ctime_r")
+ .Cases("asctime", "asctime_r", "asctime_s")
.Case("gets", "gets_s")
.Default({});
if (!AnnexKReplacementFunction.empty())
>From f6b3037227a5ffca301cc53760b42679e534b54d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 20:40:24 +0200
Subject: [PATCH 27/55] [libc][c11] implement ctime
fix: tests
---
libc/test/src/time/ctime_r_test.cpp | 21 ++++-----------------
1 file changed, 4 insertions(+), 17 deletions(-)
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index ab742368f02cc3..fe5426fc5e553d 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -14,11 +14,7 @@
using LIBC_NAMESPACE::time_utils::TimeConstants;
-static inline char *call_ctime_r(time_t *t, int year, int month, int mday,
- int hour, int min, int sec, int wday, int yday,
- char *buffer) {
- LIBC_NAMESPACE::tmhelper::testing::initialize_tm_data(
- localtime(t), year, month, mday, hour, min, sec, wday, yday);
+static inline char *call_ctime_r(time_t *t, char *buffer) {
return LIBC_NAMESPACE::ctime_r(t, buffer);
}
@@ -41,20 +37,11 @@ TEST(LlvmLibcCtimeR, Nullptr) {
ASSERT_STREQ(nullptr, result);
}
-TEST(LlvmLibcCtimeR, ValidDate) {
+TEST(LlvmLibcCtimeR, ValidUnixTimestamp) {
char buffer[TimeConstants::CTIME_BUFFER_SIZE];
- struct time_t t;
+ struct time_t t = 0;
char *result;
// 1970-01-01 00:00:00. Test with a valid buffer size.
- result = call_ctime_r(&t,
- 1970, // year
- 1, // month
- 1, // day
- 0, // hr
- 0, // min
- 0, // sec
- 4, // wday
- 0, // yday
- buffer);
+ result = call_ctime_r(&t, buffer);
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
}
>From 50b8710ee1e0b2f8df82e7d938fc9dd713f374ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 21:00:23 +0200
Subject: [PATCH 28/55] [libc][c11] implement ctime
add error if argument is greater than 32bit int and fixed tests
---
libc/src/time/ctime.cpp | 5 ++++-
libc/src/time/ctime_r.cpp | 3 +++
libc/test/src/time/ctime_r_test.cpp | 22 +++++++++++++++++++---
libc/test/src/time/ctime_test.cpp | 7 +++++++
4 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index dffebc20f47a58..cd6c893bdc8321 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -16,7 +16,10 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
- static char buffer[TimeConstants::CTIME_BUFFER_SIZE];
+ if (t_ptr > 2147483647) {
+ return llvm::createStringError(llvm::errc::invalid_argument, "ERROR");
+ }
+ static char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index 2fb7c814a822cc..73c0f2fb3f47aa 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -16,6 +16,9 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
+ if (t_ptr > 2147483647) {
+ return llvm::createStringError(llvm::errc::invalid_argument, "ERROR");
+ }
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index fe5426fc5e553d..34a385dc86c6ed 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -26,7 +26,7 @@ TEST(LlvmLibcCtimeR, Nullptr) {
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
- char buffer[TimeConstants::CTIME_BUFFER_SIZE];
+ char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
result = LIBC_NAMESPACE::ctime_r(nullptr, buffer);
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
@@ -37,11 +37,27 @@ TEST(LlvmLibcCtimeR, Nullptr) {
ASSERT_STREQ(nullptr, result);
}
-TEST(LlvmLibcCtimeR, ValidUnixTimestamp) {
- char buffer[TimeConstants::CTIME_BUFFER_SIZE];
+TEST(LlvmLibcCtimeR, ValidUnixTimestamp0) {
+ char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
struct time_t t = 0;
char *result;
// 1970-01-01 00:00:00. Test with a valid buffer size.
result = call_ctime_r(&t, buffer);
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
}
+
+TEST(LlvmLibcCtime, ValidUnixTimestamp32Int) {
+ char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
+ struct time_t t = 2147483647;
+ char *result;
+ // 2038-01-19 03:14:07. Test with a valid buffer size.
+ char* result = call_ctime_r(&t, buffer);
+ ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
+}
+
+TEST(LlvmLibcCtimeR, InvalidArgument) {
+ struct time_t t = 2147483648;
+ char* result = call_ctime(&t);
+ ASSERT_ERRNO_EQ(EINVAL);
+ ASSERT_STREQ(nullptr, result);
+}
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index c55fdb1b614aeb..e6494542ca5e39 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -34,3 +34,10 @@ TEST(LlvmLibcCtime, ValidUnixTimestamp32Int) {
char* result = call_ctime(&t);
ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
}
+
+TEST(LlvmLibcCtime, InvalidArgument) {
+ struct time_t t = 2147483648;
+ char* result = call_ctime(&t);
+ ASSERT_ERRNO_EQ(EINVAL);
+ ASSERT_STREQ(nullptr, result);
+}
>From 622579065d5ccc67910076002eee12ce4c24054c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 21:03:00 +0200
Subject: [PATCH 29/55] undo clang-tidy
---
clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index 3d326c5a3b5743..ea7eaa0b0ff811 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -42,7 +42,7 @@ static StringRef getReplacementFor(StringRef FunctionName,
// Try to find a better replacement from Annex K first.
StringRef AnnexKReplacementFunction =
StringSwitch<StringRef>(FunctionName)
- .Cases("asctime", "asctime_r", "asctime_s")
+ .Cases("asctime", "asctime_r", "asctime_s")
.Case("gets", "gets_s")
.Default({});
if (!AnnexKReplacementFunction.empty())
>From cf870c0b9ec421f137c48c04483efc7c8dcc829a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 5 Sep 2024 21:30:33 +0200
Subject: [PATCH 30/55] add header file for `time.h`
---
libc/src/time/ctime.cpp | 2 +-
libc/src/time/ctime.h | 2 +-
libc/src/time/ctime_r.cpp | 4 +++-
libc/src/time/ctime_r.h | 2 +-
libc/test/src/time/ctime_r_test.cpp | 2 +-
libc/test/src/time/ctime_test.cpp | 2 +-
6 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index cd6c893bdc8321..b14ff2607aae2d 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -23,4 +23,4 @@ LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
-} // namespace LIBC_NAMESPACE_DECL
+} // namespace LIBC_NAMESPACE_DECL
\ No newline at end of file
diff --git a/libc/src/time/ctime.h b/libc/src/time/ctime.h
index 6e9f5fa5d1382a..73c21ba3526376 100644
--- a/libc/src/time/ctime.h
+++ b/libc/src/time/ctime.h
@@ -17,4 +17,4 @@ char *ctime(const time_t *t_ptr);
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_TIME_CTIME_H
+#endif // LLVM_LIBC_SRC_TIME_CTIME_H
\ No newline at end of file
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index 73c0f2fb3f47aa..92dc8a05dad7c4 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include <time.h>
+
#include "src/time/ctime_r.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
@@ -22,4 +24,4 @@ LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
-} // namespace LIBC_NAMESPACE_DECL
+} // namespace LIBC_NAMESPACE_DECL
\ No newline at end of file
diff --git a/libc/src/time/ctime_r.h b/libc/src/time/ctime_r.h
index 93acad13c28e44..8823ef1686ddac 100644
--- a/libc/src/time/ctime_r.h
+++ b/libc/src/time/ctime_r.h
@@ -18,4 +18,4 @@ char *ctime_r(const time_t *t, char *buffer);
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_TIME_CTIME_R_H
+#endif // LLVM_LIBC_SRC_TIME_CTIME_R_H
\ No newline at end of file
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index 34a385dc86c6ed..3608e1b604ec16 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -60,4 +60,4 @@ TEST(LlvmLibcCtimeR, InvalidArgument) {
char* result = call_ctime(&t);
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
-}
+}
\ No newline at end of file
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index e6494542ca5e39..f41c3c2abe9153 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -40,4 +40,4 @@ TEST(LlvmLibcCtime, InvalidArgument) {
char* result = call_ctime(&t);
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
-}
+}
\ No newline at end of file
>From eac511ec19213d95b19c30d0984d1ddd3ac83990 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 16:59:21 +0200
Subject: [PATCH 31/55] remove `time.h`
---
libc/src/time/ctime_r.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index 92dc8a05dad7c4..0b128a01bb4f15 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -6,8 +6,6 @@
//
//===----------------------------------------------------------------------===//
-#include <time.h>
-
#include "src/time/ctime_r.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
>From 2f2a9a089c4789aee9e93c969ceaf3d1d908295e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 17:01:15 +0200
Subject: [PATCH 32/55] add function for `localtime` that temporarily use
`gmtime`, since `localtime` is not yet implemented
---
libc/src/time/time_utils.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 47f55f7d389122..bbc809efc842a3 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -156,6 +156,13 @@ LIBC_INLINE struct tm *gmtime_internal(const time_t *timer, struct tm *result) {
return result;
}
+// TODO: localtime is not yet implemented and a temporary solution is to
+// use gmtime
+LIBC_INLINE struct tm *localtime(const time_t *timer, struct tm *result) {
+ struct tm *result = {0};
+ return time_utils::gmtime_internal(t_ptr, result);
+}
+
} // namespace time_utils
} // namespace LIBC_NAMESPACE_DECL
>From 602486b4d4f3747175debc44545fe90697acd01d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 17:26:18 +0200
Subject: [PATCH 33/55] added github issue for implementing `localtime`
---
libc/src/time/time_utils.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index bbc809efc842a3..4e1d727982a6b9 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -157,7 +157,7 @@ LIBC_INLINE struct tm *gmtime_internal(const time_t *timer, struct tm *result) {
}
// TODO: localtime is not yet implemented and a temporary solution is to
-// use gmtime
+// use gmtime, https://github.com/llvm/llvm-project/issues/107597
LIBC_INLINE struct tm *localtime(const time_t *timer, struct tm *result) {
struct tm *result = {0};
return time_utils::gmtime_internal(t_ptr, result);
>From eadea599de626533bf6733692ad53df41185e4c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:00:14 +0200
Subject: [PATCH 34/55] remove `struct tm` from `localtime`
---
libc/src/time/time_utils.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 4e1d727982a6b9..948602c32c584e 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -158,7 +158,7 @@ LIBC_INLINE struct tm *gmtime_internal(const time_t *timer, struct tm *result) {
// TODO: localtime is not yet implemented and a temporary solution is to
// use gmtime, https://github.com/llvm/llvm-project/issues/107597
-LIBC_INLINE struct tm *localtime(const time_t *timer, struct tm *result) {
+LIBC_INLINE struct tm *localtime(const time_t *timer) {
struct tm *result = {0};
return time_utils::gmtime_internal(t_ptr, result);
}
>From 325de682ad4273c93d93081398c9a2e45cf8b641 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:04:42 +0200
Subject: [PATCH 35/55] use relative path
---
libc/src/time/ctime.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index b14ff2607aae2d..49e766c0950472 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "ctime.h"
-#include "../__support/common.h"
-#include "../__support/macros/config.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
#include "time_utils.h"
namespace LIBC_NAMESPACE_DECL {
>From 42c0508841efabcd35ff58025a97978276d22063 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:06:40 +0200
Subject: [PATCH 36/55] add newline at end of files
---
libc/src/time/ctime.cpp | 2 +-
libc/src/time/ctime_r.cpp | 2 +-
libc/test/src/time/ctime_r_test.cpp | 2 +-
libc/test/src/time/ctime_test.cpp | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 49e766c0950472..29b4ee2afcbac7 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -23,4 +23,4 @@ LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
-} // namespace LIBC_NAMESPACE_DECL
\ No newline at end of file
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index 0b128a01bb4f15..73c0f2fb3f47aa 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -22,4 +22,4 @@ LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
-} // namespace LIBC_NAMESPACE_DECL
\ No newline at end of file
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index 3608e1b604ec16..34a385dc86c6ed 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -60,4 +60,4 @@ TEST(LlvmLibcCtimeR, InvalidArgument) {
char* result = call_ctime(&t);
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
-}
\ No newline at end of file
+}
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index f41c3c2abe9153..e6494542ca5e39 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -40,4 +40,4 @@ TEST(LlvmLibcCtime, InvalidArgument) {
char* result = call_ctime(&t);
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
-}
\ No newline at end of file
+}
>From 2e51762d175f1005206dd53b237d419e13332753 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:07:55 +0200
Subject: [PATCH 37/55] add comment for tests
---
libc/test/src/time/ctime_r_test.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index 34a385dc86c6ed..52ed2dde73bddc 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -14,6 +14,7 @@
using LIBC_NAMESPACE::time_utils::TimeConstants;
+// make check-libc LIBC_TEST_TARGET=call_ctime_r VERBOSE=1
static inline char *call_ctime_r(time_t *t, char *buffer) {
return LIBC_NAMESPACE::ctime_r(t, buffer);
}
>From 9137851d1d899d3475798d0f2866de92a1baff5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:11:10 +0200
Subject: [PATCH 38/55] add newline to end of files
---
libc/src/time/ctime.h | 2 +-
libc/src/time/ctime_r.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/time/ctime.h b/libc/src/time/ctime.h
index 73c21ba3526376..6e9f5fa5d1382a 100644
--- a/libc/src/time/ctime.h
+++ b/libc/src/time/ctime.h
@@ -17,4 +17,4 @@ char *ctime(const time_t *t_ptr);
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_TIME_CTIME_H
\ No newline at end of file
+#endif // LLVM_LIBC_SRC_TIME_CTIME_H
diff --git a/libc/src/time/ctime_r.h b/libc/src/time/ctime_r.h
index 8823ef1686ddac..93acad13c28e44 100644
--- a/libc/src/time/ctime_r.h
+++ b/libc/src/time/ctime_r.h
@@ -18,4 +18,4 @@ char *ctime_r(const time_t *t, char *buffer);
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_TIME_CTIME_R_H
\ No newline at end of file
+#endif // LLVM_LIBC_SRC_TIME_CTIME_R_H
>From 485e7fbdd6ff47d48fd32ccdc1d399b7f3afec0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:18:00 +0200
Subject: [PATCH 39/55] return `nullptr` if `time_t` is greater than 32bit
value
---
libc/src/time/ctime.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 29b4ee2afcbac7..4aa1e7e5e220e1 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -17,7 +17,7 @@ using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
if (t_ptr > 2147483647) {
- return llvm::createStringError(llvm::errc::invalid_argument, "ERROR");
+ return nullptr;
}
static char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
>From 3a44b7aa2c1ad8054f9f4dd8fc3235540b6fd5f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:24:22 +0200
Subject: [PATCH 40/55] return `nullptr` if `time_t` is greater than 32bit
value
---
libc/src/time/ctime_r.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index 73c0f2fb3f47aa..b781613e91babb 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -17,7 +17,7 @@ using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
if (t_ptr > 2147483647) {
- return llvm::createStringError(llvm::errc::invalid_argument, "ERROR");
+ return nullptr;
}
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
>From cd47d24a22c2f4c85d53621392f2cd4d504f0913 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:34:42 +0200
Subject: [PATCH 41/55] add 32bit maximum value to `TimeConstants` struct
---
libc/src/time/ctime.cpp | 2 +-
libc/src/time/ctime_r.cpp | 2 +-
libc/src/time/time_utils.h | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 4aa1e7e5e220e1..13432e88e08fa7 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
- if (t_ptr > 2147483647) {
+ if (t_ptr > TimeConstants::MAXIMUM_32_BIT_VALUE) {
return nullptr;
}
static char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index b781613e91babb..a8df3bfec36230 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
- if (t_ptr > 2147483647) {
+ if (t_ptr > TimeConstants::MAXIMUM_32_BIT_VALUE) {
return nullptr;
}
return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 948602c32c584e..cc4d4b477b76d2 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -37,6 +37,7 @@ enum Month : int {
};
struct TimeConstants {
+ static constexpr int MAXIMUM_32_BIT_VALUE = 2147483647;
static constexpr int SECONDS_PER_MIN = 60;
static constexpr int MINUTES_PER_HOUR = 60;
static constexpr int HOURS_PER_DAY = 24;
>From a28d5cb8e18f1aa5992097e42f30cdf1af3ce4bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 18:48:14 +0200
Subject: [PATCH 42/55] use `time_t.h` and include it in dependencies for
`ctime` and `ctime_t`
---
libc/src/time/CMakeLists.txt | 2 ++
libc/src/time/ctime_r.h | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 1605a6b897c14b..b3318e7ca87fa5 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -44,6 +44,7 @@ add_entrypoint_object(
ctime.h
DEPENDS
.time_utils
+ libc.hdr.types.time_t
libc.include.time
)
@@ -55,6 +56,7 @@ add_entrypoint_object(
ctime_r.h
DEPENDS
.time_utils
+ libc.hdr.types.time_t
libc.include.time
)
diff --git a/libc/src/time/ctime_r.h b/libc/src/time/ctime_r.h
index 93acad13c28e44..2ab4f7c3b62379 100644
--- a/libc/src/time/ctime_r.h
+++ b/libc/src/time/ctime_r.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC_TIME_CTIME_R_H
#define LLVM_LIBC_SRC_TIME_CTIME_R_H
+#include "hdr/types/time_t.h"
#include "src/__support/macros/config.h"
-#include <time.h>
namespace LIBC_NAMESPACE_DECL {
>From 3647f4062ea41b95d7e3be466136ec4de8d4e300 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 19:37:22 +0200
Subject: [PATCH 43/55] update cmake for tests
---
libc/test/src/time/CMakeLists.txt | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 78cfe8f301615f..0c6637f8c780b1 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -30,6 +30,36 @@ add_libc_unittest(
libc.src.time.asctime_r
)
+add_libc_unittest(
+ ctime_test
+ SUITE
+ libc_time_unittests
+ SRCS
+ ctime_test.cpp
+ HDRS
+ TmHelper.h
+ TmMatcher.h
+ CXX_STANDARD
+ 20
+ DEPENDS
+ libc.src.time.ctime
+)
+
+add_libc_unittest(
+ ctime_r_test
+ SUITE
+ libc_time_unittests
+ SRCS
+ ctime_r_test.cpp
+ HDRS
+ TmHelper.h
+ TmMatcher.h
+ CXX_STANDARD
+ 20
+ DEPENDS
+ libc.src.time.ctime_r
+)
+
add_libc_test(
clock_gettime_test
SUITE
>From 592e21c695f12c90a5e954e3b2ae598d0e9ebe5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 20:05:45 +0200
Subject: [PATCH 44/55] remove symbols, since these will be implemented in
https://github.com/llvm/llvm-project/issues/107445
---
clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc | 1 -
clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc | 3 ---
2 files changed, 4 deletions(-)
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
index b1f7dc286429cd..463ce921f0672f 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
@@ -220,7 +220,6 @@ SYMBOL(and, None, <iso646.h>)
SYMBOL(and_eq, None, <iso646.h>)
SYMBOL(asctime, None, <time.h>)
SYMBOL(asctime_s, None, <time.h>)
-SYMBOL(ctime, None, <time.h>)
SYMBOL(asin, None, <math.h>)
SYMBOL(asinf, None, <math.h>)
SYMBOL(asinh, None, <math.h>)
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
index 7f0e32b6233e9c..b46bd2e4d7a4b5 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -617,9 +617,6 @@ SYMBOL(as_writable_bytes, std::, <span>)
SYMBOL(asctime, std::, <ctime>)
SYMBOL(asctime, None, <ctime>)
SYMBOL(asctime, None, <time.h>)
-SYMBOL(ctime, std::, <ctime>)
-SYMBOL(ctime, None, <ctime>)
-SYMBOL(ctime, None, <time.h>)
SYMBOL(asin, std::, <cmath>)
SYMBOL(asin, None, <cmath>)
SYMBOL(asin, None, <math.h>)
>From 73e65a0c9ecb57d43c5616a19cc654ea30cc0cbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Fri, 6 Sep 2024 21:19:37 +0200
Subject: [PATCH 45/55] update cmake for tests
---
libc/test/src/time/CMakeLists.txt | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 0c6637f8c780b1..bba01f063fed27 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -42,7 +42,10 @@ add_libc_unittest(
CXX_STANDARD
20
DEPENDS
+ libc.include.time
+ libc.hdr.types.time_t
libc.src.time.ctime
+ libc.src.time.time_utils
)
add_libc_unittest(
@@ -57,7 +60,10 @@ add_libc_unittest(
CXX_STANDARD
20
DEPENDS
+ libc.include.time
+ libc.hdr.types.time_t
libc.src.time.ctime_r
+ libc.src.time.time_utils
)
add_libc_test(
>From b9c6ceb0cb7a83dc729deac9762f3da7e68fa11e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Sun, 8 Sep 2024 17:44:15 +0200
Subject: [PATCH 46/55] use `time_utils::localtime`
---
libc/src/time/ctime.cpp | 2 +-
libc/src/time/ctime_r.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 13432e88e08fa7..7241aba876808e 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -20,7 +20,7 @@ LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
return nullptr;
}
static char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
- return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
+ return time_utils::asctime(time_utils::localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index a8df3bfec36230..08bd76a6ac3b98 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
if (t_ptr > TimeConstants::MAXIMUM_32_BIT_VALUE) {
return nullptr;
}
- return time_utils::asctime(localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
+ return time_utils::asctime(time_utils::localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
>From c130c1fcd53a4411fb1751a1c436f4f4ff2691d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Sun, 8 Sep 2024 17:45:23 +0200
Subject: [PATCH 47/55] use `cpp::numeric_limits<int32_t>::max()`
---
libc/src/time/ctime.cpp | 2 +-
libc/src/time/ctime_r.cpp | 2 +-
libc/src/time/time_utils.h | 1 -
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 7241aba876808e..82227d70c2b70f 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
- if (t_ptr > TimeConstants::MAXIMUM_32_BIT_VALUE) {
+ if (t_ptr > cpp::numeric_limits<int32_t>::max()) {
return nullptr;
}
static char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index 08bd76a6ac3b98..748e1831cba5b2 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
- if (t_ptr > TimeConstants::MAXIMUM_32_BIT_VALUE) {
+ if (t_ptr > cpp::numeric_limits<int32_t>::max()) {
return nullptr;
}
return time_utils::asctime(time_utils::localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index cc4d4b477b76d2..948602c32c584e 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -37,7 +37,6 @@ enum Month : int {
};
struct TimeConstants {
- static constexpr int MAXIMUM_32_BIT_VALUE = 2147483647;
static constexpr int SECONDS_PER_MIN = 60;
static constexpr int MINUTES_PER_HOUR = 60;
static constexpr int HOURS_PER_DAY = 24;
>From 49192799b4ca050f56f4d15e11e8b58a59c84791 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Sun, 8 Sep 2024 17:46:58 +0200
Subject: [PATCH 48/55] pointer should be dereferenced
---
libc/src/time/ctime.cpp | 2 +-
libc/src/time/ctime_r.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 82227d70c2b70f..7fa2979ce15a1d 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
- if (t_ptr > cpp::numeric_limits<int32_t>::max()) {
+ if (*t_ptr > cpp::numeric_limits<int32_t>::max()) {
return nullptr;
}
static char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index 748e1831cba5b2..19b4ec9cfd0ea6 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
using LIBC_NAMESPACE::time_utils::TimeConstants;
LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
- if (t_ptr > cpp::numeric_limits<int32_t>::max()) {
+ if (*t_ptr > cpp::numeric_limits<int32_t>::max()) {
return nullptr;
}
return time_utils::asctime(time_utils::localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
>From 4cda79adb70e32a8de5a835dc353e3ffdb89b890 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Sun, 8 Sep 2024 17:48:15 +0200
Subject: [PATCH 49/55] update comment for tests
---
libc/test/src/time/ctime_r_test.cpp | 2 +-
libc/test/src/time/ctime_test.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index 52ed2dde73bddc..bd9b99753aa448 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -14,7 +14,7 @@
using LIBC_NAMESPACE::time_utils::TimeConstants;
-// make check-libc LIBC_TEST_TARGET=call_ctime_r VERBOSE=1
+// make libc.test.src.time.ctime_r_test
static inline char *call_ctime_r(time_t *t, char *buffer) {
return LIBC_NAMESPACE::ctime_r(t, buffer);
}
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index e6494542ca5e39..cad257d05acc49 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// make check-libc LIBC_TEST_TARGET=call_ctime VERBOSE=1
+// make libc.test.src.time.ctime_test
#include "src/errno/libc_errno.h"
#include "src/time/ctime.h"
#include "test/UnitTest/Test.h"
>From 85281728c8cf5dd400cbe7788ef7438a7ebd6c3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Mon, 9 Sep 2024 20:25:58 +0200
Subject: [PATCH 50/55] remove helper functions and update comments
---
libc/test/src/time/ctime_r_test.cpp | 10 ++--------
libc/test/src/time/ctime_test.cpp | 12 ++++--------
2 files changed, 6 insertions(+), 16 deletions(-)
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index bd9b99753aa448..8c765bb638e22a 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -15,12 +15,6 @@
using LIBC_NAMESPACE::time_utils::TimeConstants;
// make libc.test.src.time.ctime_r_test
-static inline char *call_ctime_r(time_t *t, char *buffer) {
- return LIBC_NAMESPACE::ctime_r(t, buffer);
-}
-
-// ctime and ctime_r share the same code and thus didn't repeat all the
-// tests from ctime. Added couple of validation tests.
TEST(LlvmLibcCtimeR, Nullptr) {
char *result;
result = LIBC_NAMESPACE::ctime_r(nullptr, nullptr);
@@ -43,7 +37,7 @@ TEST(LlvmLibcCtimeR, ValidUnixTimestamp0) {
struct time_t t = 0;
char *result;
// 1970-01-01 00:00:00. Test with a valid buffer size.
- result = call_ctime_r(&t, buffer);
+ result = LIBC_NAMESPACE::ctime_r(t, buffer);
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
}
@@ -52,7 +46,7 @@ TEST(LlvmLibcCtime, ValidUnixTimestamp32Int) {
struct time_t t = 2147483647;
char *result;
// 2038-01-19 03:14:07. Test with a valid buffer size.
- char* result = call_ctime_r(&t, buffer);
+ char* result = LIBC_NAMESPACE::ctime_r(t, buffer);
ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
}
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index cad257d05acc49..14b6ab908f9b4d 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -6,16 +6,12 @@
//
//===----------------------------------------------------------------------===//
-// make libc.test.src.time.ctime_test
#include "src/errno/libc_errno.h"
#include "src/time/ctime.h"
#include "test/UnitTest/Test.h"
#include "test/src/time/TmHelper.h"
-static inline char *call_ctime(struct time_t *t) {
- return LIBC_NAMESPACE::ctime(t);
-}
-
+// make libc.test.src.time.ctime_test
TEST(LlvmLibcCtime, Nullptr) {
char *result;
result = LIBC_NAMESPACE::ctime(nullptr);
@@ -25,19 +21,19 @@ TEST(LlvmLibcCtime, Nullptr) {
TEST(LlvmLibcCtime, ValidUnixTimestamp0) {
struct time_t t = 0;
- char* result = call_ctime(&t);
+ char* result = LIBC_NAMESPACE::ctime(t);
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
}
TEST(LlvmLibcCtime, ValidUnixTimestamp32Int) {
struct time_t t = 2147483647;
- char* result = call_ctime(&t);
+ char* result = LIBC_NAMESPACE::ctime(t);
ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
}
TEST(LlvmLibcCtime, InvalidArgument) {
struct time_t t = 2147483648;
- char* result = call_ctime(&t);
+ char* result = LIBC_NAMESPACE::ctime(t);
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
}
>From 4543afa9f9fd5e4188f888ba1243866be1ddbe66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Mon, 9 Sep 2024 20:29:38 +0200
Subject: [PATCH 51/55] `result` should be `static`
---
libc/src/time/time_utils.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 948602c32c584e..4392ced09dc3fb 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -159,8 +159,8 @@ LIBC_INLINE struct tm *gmtime_internal(const time_t *timer, struct tm *result) {
// TODO: localtime is not yet implemented and a temporary solution is to
// use gmtime, https://github.com/llvm/llvm-project/issues/107597
LIBC_INLINE struct tm *localtime(const time_t *timer) {
- struct tm *result = {0};
- return time_utils::gmtime_internal(t_ptr, result);
+ static struct tm result;
+ return time_utils::gmtime_internal(t_ptr, &result);
}
} // namespace time_utils
>From ac16aa603ad42607d8602c2d5e4b4aa639f6131f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Mon, 9 Sep 2024 20:31:08 +0200
Subject: [PATCH 52/55] remove comments
---
libc/test/src/time/ctime_r_test.cpp | 1 -
libc/test/src/time/ctime_test.cpp | 1 -
2 files changed, 2 deletions(-)
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index 8c765bb638e22a..33feb838f1efec 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -14,7 +14,6 @@
using LIBC_NAMESPACE::time_utils::TimeConstants;
-// make libc.test.src.time.ctime_r_test
TEST(LlvmLibcCtimeR, Nullptr) {
char *result;
result = LIBC_NAMESPACE::ctime_r(nullptr, nullptr);
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index 14b6ab908f9b4d..559e7f39f2484c 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -11,7 +11,6 @@
#include "test/UnitTest/Test.h"
#include "test/src/time/TmHelper.h"
-// make libc.test.src.time.ctime_test
TEST(LlvmLibcCtime, Nullptr) {
char *result;
result = LIBC_NAMESPACE::ctime(nullptr);
>From badde0df8c9202dfc9168a064db21567ef6557e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Wed, 11 Sep 2024 14:57:49 +0200
Subject: [PATCH 53/55] removed `ctime` and `ctime_r` from clang fmt
---
clang/docs/tools/clang-formatted-files.txt | 4 ----
1 file changed, 4 deletions(-)
diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt
index 2261a726235c1b..fc07357986d989 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -3062,10 +3062,6 @@ libc/src/time/asctime.cpp
libc/src/time/asctime.h
libc/src/time/asctime_r.cpp
libc/src/time/asctime_r.h
-libc/src/time/ctime.cpp
-libc/src/time/ctime.h
-libc/src/time/ctime_r.cpp
-libc/src/time/ctime_r.h
libc/src/time/gmtime.cpp
libc/src/time/gmtime.h
libc/src/time/gmtime_r.cpp
>From 30ba340dfcc9342f01fb3bdb9fce380ff38d644e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 12 Sep 2024 00:13:15 +0200
Subject: [PATCH 54/55] format code with clang-format
---
libc/src/time/ctime.cpp | 3 ++-
libc/src/time/ctime_r.cpp | 3 ++-
libc/test/src/time/ctime_r_test.cpp | 4 ++--
libc/test/src/time/ctime_test.cpp | 6 +++---
4 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/libc/src/time/ctime.cpp b/libc/src/time/ctime.cpp
index 7fa2979ce15a1d..80695895c355e8 100644
--- a/libc/src/time/ctime.cpp
+++ b/libc/src/time/ctime.cpp
@@ -20,7 +20,8 @@ LLVM_LIBC_FUNCTION(char *, ctime, (const time_t *t_ptr)) {
return nullptr;
}
static char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
- return time_utils::asctime(time_utils::localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
+ return time_utils::asctime(time_utils::localtime(t_ptr), buffer,
+ TimeConstants::ASCTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/ctime_r.cpp b/libc/src/time/ctime_r.cpp
index 19b4ec9cfd0ea6..4d6bce780c40b6 100644
--- a/libc/src/time/ctime_r.cpp
+++ b/libc/src/time/ctime_r.cpp
@@ -19,7 +19,8 @@ LLVM_LIBC_FUNCTION(char *, ctime_r, (const time_t *t_ptr, char *buffer)) {
if (*t_ptr > cpp::numeric_limits<int32_t>::max()) {
return nullptr;
}
- return time_utils::asctime(time_utils::localtime(t_ptr), buffer, TimeConstants::ASCTIME_MAX_BYTES);
+ return time_utils::asctime(time_utils::localtime(t_ptr), buffer,
+ TimeConstants::ASCTIME_MAX_BYTES);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/time/ctime_r_test.cpp b/libc/test/src/time/ctime_r_test.cpp
index 33feb838f1efec..26b41f98a828d1 100644
--- a/libc/test/src/time/ctime_r_test.cpp
+++ b/libc/test/src/time/ctime_r_test.cpp
@@ -45,13 +45,13 @@ TEST(LlvmLibcCtime, ValidUnixTimestamp32Int) {
struct time_t t = 2147483647;
char *result;
// 2038-01-19 03:14:07. Test with a valid buffer size.
- char* result = LIBC_NAMESPACE::ctime_r(t, buffer);
+ char *result = LIBC_NAMESPACE::ctime_r(t, buffer);
ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
}
TEST(LlvmLibcCtimeR, InvalidArgument) {
struct time_t t = 2147483648;
- char* result = call_ctime(&t);
+ char *result = call_ctime(&t);
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
}
diff --git a/libc/test/src/time/ctime_test.cpp b/libc/test/src/time/ctime_test.cpp
index 559e7f39f2484c..7e158f1df33802 100644
--- a/libc/test/src/time/ctime_test.cpp
+++ b/libc/test/src/time/ctime_test.cpp
@@ -20,19 +20,19 @@ TEST(LlvmLibcCtime, Nullptr) {
TEST(LlvmLibcCtime, ValidUnixTimestamp0) {
struct time_t t = 0;
- char* result = LIBC_NAMESPACE::ctime(t);
+ char *result = LIBC_NAMESPACE::ctime(t);
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
}
TEST(LlvmLibcCtime, ValidUnixTimestamp32Int) {
struct time_t t = 2147483647;
- char* result = LIBC_NAMESPACE::ctime(t);
+ char *result = LIBC_NAMESPACE::ctime(t);
ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
}
TEST(LlvmLibcCtime, InvalidArgument) {
struct time_t t = 2147483648;
- char* result = LIBC_NAMESPACE::ctime(t);
+ char *result = LIBC_NAMESPACE::ctime(t);
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_STREQ(nullptr, result);
}
>From 553c777ef30863f9b11d5d2d9bafe947865d8402 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
=?UTF-8?q?=D0=B0?= <149377404+zimirza at users.noreply.github.com>
Date: Thu, 12 Sep 2024 06:59:16 +0200
Subject: [PATCH 55/55] fix: function argument
---
libc/src/time/time_utils.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 4392ced09dc3fb..552ea925c1c7dc 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -158,7 +158,7 @@ LIBC_INLINE struct tm *gmtime_internal(const time_t *timer, struct tm *result) {
// TODO: localtime is not yet implemented and a temporary solution is to
// use gmtime, https://github.com/llvm/llvm-project/issues/107597
-LIBC_INLINE struct tm *localtime(const time_t *timer) {
+LIBC_INLINE struct tm *localtime(const time_t *t_ptr) {
static struct tm result;
return time_utils::gmtime_internal(t_ptr, &result);
}
More information about the libc-commits
mailing list