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+zimi...@users.noreply.github.com> Date: Tue, 3 Sep 2024 22:47:30 +0200 Subject: [PATCH 01/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 18:51:34 +0200 Subject: [PATCH 02/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:11:37 +0200 Subject: [PATCH 03/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:27:58 +0200 Subject: [PATCH 04/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:43:41 +0200 Subject: [PATCH 05/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:55:59 +0200 Subject: [PATCH 06/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 20:01:34 +0200 Subject: [PATCH 07/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 20:09:03 +0200 Subject: [PATCH 08/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 20:23:15 +0200 Subject: [PATCH 09/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 20:25:49 +0200 Subject: [PATCH 10/45] [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+zimi...@users.noreply.github.com> Date: Wed, 4 Sep 2024 20:27:31 +0200 Subject: [PATCH 11/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:02:46 +0200 Subject: [PATCH 12/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:04:07 +0200 Subject: [PATCH 13/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:10:02 +0200 Subject: [PATCH 14/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:14:14 +0200 Subject: [PATCH 15/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:04:59 +0200 Subject: [PATCH 16/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:06:10 +0200 Subject: [PATCH 17/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:34:17 +0200 Subject: [PATCH 18/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:58:51 +0200 Subject: [PATCH 19/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:13:43 +0200 Subject: [PATCH 20/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:49:58 +0200 Subject: [PATCH 21/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:51:08 +0200 Subject: [PATCH 22/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:19:06 +0200 Subject: [PATCH 23/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:19:43 +0200 Subject: [PATCH 24/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:23:33 +0200 Subject: [PATCH 25/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:31:35 +0200 Subject: [PATCH 26/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:40:24 +0200 Subject: [PATCH 27/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 21:00:23 +0200 Subject: [PATCH 28/45] [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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 21:03:00 +0200 Subject: [PATCH 29/45] 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+zimi...@users.noreply.github.com> Date: Thu, 5 Sep 2024 21:30:33 +0200 Subject: [PATCH 30/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:59:21 +0200 Subject: [PATCH 31/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:01:15 +0200 Subject: [PATCH 32/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:26:18 +0200 Subject: [PATCH 33/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:00:14 +0200 Subject: [PATCH 34/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:04:42 +0200 Subject: [PATCH 35/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:06:40 +0200 Subject: [PATCH 36/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:07:55 +0200 Subject: [PATCH 37/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:11:10 +0200 Subject: [PATCH 38/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:18:00 +0200 Subject: [PATCH 39/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:24:22 +0200 Subject: [PATCH 40/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:34:42 +0200 Subject: [PATCH 41/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:48:14 +0200 Subject: [PATCH 42/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 19:37:22 +0200 Subject: [PATCH 43/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 20:05:45 +0200 Subject: [PATCH 44/45] 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+zimi...@users.noreply.github.com> Date: Fri, 6 Sep 2024 21:19:37 +0200 Subject: [PATCH 45/45] 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( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits