[libc-commits] [libc] a72499e - [libc] Introduce asctime, asctime_r to LLVM libc
Raman Tenneti via libc-commits
libc-commits at lists.llvm.org
Mon May 3 17:15:31 PDT 2021
Author: Raman Tenneti
Date: 2021-05-03T17:15:00-07:00
New Revision: a72499e47537c02a33d7c1c2e512d0b4a0ecbb89
URL: https://github.com/llvm/llvm-project/commit/a72499e47537c02a33d7c1c2e512d0b4a0ecbb89
DIFF: https://github.com/llvm/llvm-project/commit/a72499e47537c02a33d7c1c2e512d0b4a0ecbb89.diff
LOG: [libc] Introduce asctime, asctime_r to LLVM libc
[libc] Introduce asctime, asctime_r to LLVM libc
asctime and asctime_r share the same common code. They call asctime_internal
a static inline function.
asctime uses snprintf to return the string representation in a buffer.
It uses the following format (26 characters is the buffer size) as per
7.27.3.1 section in http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2478.pdf.
The buf parameter for asctime_r shall point to a buffer of at least 26 bytes.
snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",...)
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D99686
Added:
libc/src/time/asctime.cpp
libc/src/time/asctime.h
libc/src/time/asctime_r.cpp
libc/src/time/asctime_r.h
libc/test/src/time/TmHelper.h
libc/test/src/time/asctime_r_test.cpp
libc/test/src/time/asctime_test.cpp
Modified:
libc/config/linux/api.td
libc/config/linux/x86_64/entrypoints.txt
libc/spec/stdc.td
libc/src/time/CMakeLists.txt
libc/src/time/time_utils.h
libc/test/src/time/CMakeLists.txt
libc/test/src/time/mktime_test.cpp
Removed:
################################################################################
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 36067fbbf22fe..c68888ab3c700 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -249,6 +249,8 @@ def TimeAPI : PublicAPI<"time.h"> {
];
let Functions = [
+ "asctime",
+ "asctime_r",
"gmtime",
"gmtime_r",
"mktime",
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 678cc460d28a3..764059d692127 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -181,6 +181,8 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.threads.thrd_join
# time.h entrypoints
+ libc.src.time.asctime
+ libc.src.time.asctime_r
libc.src.time.gmtime
libc.src.time.gmtime_r
libc.src.time.mktime
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index f771ad3249e51..b50d2ed44d73b 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -599,6 +599,19 @@ def StdC : StandardSpec<"stdc"> {
],
[], // Enumerations
[
+ FunctionSpec<
+ "asctime",
+ RetValSpec<CharPtr>,
+ [ArgSpec<StructTmPtr>]
+ >,
+ FunctionSpec<
+ "asctime_r",
+ RetValSpec<CharPtr>,
+ [
+ ArgSpec<StructTmPtr>,
+ ArgSpec<CharPtr>,
+ ]
+ >,
FunctionSpec<
"gmtime",
RetValSpec<StructTmPtr>,
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 03343cf036c53..7e849cf0543ae 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -10,6 +10,28 @@ add_object_library(
libc.src.errno.__errno_location
)
+add_entrypoint_object(
+ asctime
+ SRCS
+ asctime.cpp
+ HDRS
+ asctime.h
+ DEPENDS
+ .time_utils
+ libc.include.time
+)
+
+add_entrypoint_object(
+ asctime_r
+ SRCS
+ asctime_r.cpp
+ HDRS
+ asctime_r.h
+ DEPENDS
+ .time_utils
+ libc.include.time
+)
+
add_entrypoint_object(
gmtime
SRCS
diff --git a/libc/src/time/asctime.cpp b/libc/src/time/asctime.cpp
new file mode 100644
index 0000000000000..cdf5391d29ebf
--- /dev/null
+++ b/libc/src/time/asctime.cpp
@@ -0,0 +1,22 @@
+//===-- 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/asctime.h"
+#include "src/__support/common.h"
+#include "src/time/time_utils.h"
+
+namespace __llvm_libc {
+
+using __llvm_libc::time_utils::TimeConstants;
+
+LLVM_LIBC_FUNCTION(char *, asctime, (const struct tm *timeptr)) {
+ static char buffer[TimeConstants::AsctimeBufferSize];
+ return time_utils::asctime(timeptr, buffer, TimeConstants::AsctimeMaxBytes);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/time/asctime.h b/libc/src/time/asctime.h
new file mode 100644
index 0000000000000..9d75b40148afd
--- /dev/null
+++ b/libc/src/time/asctime.h
@@ -0,0 +1,22 @@
+//===-- Implementation header of asctime ------------------------*- 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_H
+#define LLVM_LIBC_SRC_TIME_ASCTIME_H
+
+#include <time.h>
+
+namespace __llvm_libc {
+
+char *asctime(const struct tm *timeptr);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_TIME_ASCTIME_H
+
+#include "include/time.h"
diff --git a/libc/src/time/asctime_r.cpp b/libc/src/time/asctime_r.cpp
new file mode 100644
index 0000000000000..fadc13e3b5a02
--- /dev/null
+++ b/libc/src/time/asctime_r.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of asctime_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/asctime_r.h"
+#include "src/__support/common.h"
+#include "src/time/time_utils.h"
+
+namespace __llvm_libc {
+
+using __llvm_libc::time_utils::TimeConstants;
+
+LLVM_LIBC_FUNCTION(char *, asctime_r,
+ (const struct tm *timeptr, char *buffer)) {
+ return time_utils::asctime(timeptr, buffer, TimeConstants::AsctimeMaxBytes);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/time/asctime_r.h b/libc/src/time/asctime_r.h
new file mode 100644
index 0000000000000..8521e782a509d
--- /dev/null
+++ b/libc/src/time/asctime_r.h
@@ -0,0 +1,22 @@
+//===-- Implementation header of asctime_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 <time.h>
+
+namespace __llvm_libc {
+
+char *asctime_r(const struct tm *timeptr, char *buffer);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_TIME_ASCTIME_R_H
+
+#include "include/time.h"
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index cca03007084c9..c1c7735f49060 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -9,6 +9,8 @@
#ifndef LLVM_LIBC_SRC_TIME_TIME_UTILS_H
#define LLVM_LIBC_SRC_TIME_TIME_UTILS_H
+#include <stddef.h> // For size_t.
+
#include "include/errno.h"
#include "src/errno/llvmlibc_errno.h"
@@ -33,6 +35,14 @@ struct TimeConstants {
static constexpr int NumberOfSecondsInLeapYear =
(DaysPerNonLeapYear + 1) * SecondsPerDay;
+ // For asctime the behavior is undefined if struct tm's tm_wday or tm_mon are
+ // not within the normal ranges as defined in <time.h>, or if struct tm's
+ // tm_year exceeds {INT_MAX}-1990, or if the below asctime_internal algorithm
+ // would attempt to generate more than 26 bytes of output (including the
+ // terminating null).
+ static constexpr int AsctimeBufferSize = 256;
+ static constexpr int AsctimeMaxBytes = 26;
+
/* 2000-03-01 (mod 400 year, immediately after feb29 */
static constexpr int64_t SecondsUntil2000MarchFirst =
(946684800LL + SecondsPerDay * (31 + 29));
@@ -63,6 +73,46 @@ static inline time_t OutOfRange() {
return static_cast<time_t>(-1);
}
+static inline void InvalidValue() { llvmlibc_errno = EINVAL; }
+
+static inline char *asctime(const struct tm *timeptr, char *buffer,
+ size_t bufferLength) {
+ if (timeptr == nullptr || buffer == nullptr) {
+ InvalidValue();
+ return nullptr;
+ }
+ if (timeptr->tm_wday < 0 ||
+ timeptr->tm_wday > (TimeConstants::DaysPerWeek - 1)) {
+ InvalidValue();
+ return nullptr;
+ }
+ if (timeptr->tm_mon < 0 ||
+ timeptr->tm_mon > (TimeConstants::MonthsPerYear - 1)) {
+ InvalidValue();
+ return nullptr;
+ }
+
+ // TODO(rtenneti): i18n the following strings.
+ static const char *WeekDaysName[TimeConstants::DaysPerWeek] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+
+ static const char *MonthsName[TimeConstants::MonthsPerYear] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+ int written_size = __builtin_snprintf(
+ buffer, bufferLength, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ WeekDaysName[timeptr->tm_wday], MonthsName[timeptr->tm_mon],
+ timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec,
+ TimeConstants::TimeYearBase + timeptr->tm_year);
+ if (written_size < 0)
+ return nullptr;
+ if (static_cast<size_t>(written_size) >= bufferLength) {
+ OutOfRange();
+ return nullptr;
+ }
+ return buffer;
+}
+
static inline struct tm *gmtime_internal(const time_t *timer,
struct tm *result) {
int64_t seconds = *timer;
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index e3bf5e228c653..514a6faa57039 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -1,5 +1,31 @@
add_libc_testsuite(libc_time_unittests)
+add_libc_unittest(
+ asctime
+ SUITE
+ libc_time_unittests
+ SRCS
+ asctime_test.cpp
+ HDRS
+ TmHelper.h
+ TmMatcher.h
+ DEPENDS
+ libc.src.time.asctime
+)
+
+add_libc_unittest(
+ asctime_r
+ SUITE
+ libc_time_unittests
+ SRCS
+ asctime_r_test.cpp
+ HDRS
+ TmHelper.h
+ TmMatcher.h
+ DEPENDS
+ libc.src.time.asctime_r
+)
+
add_libc_unittest(
gmtime
SUITE
@@ -31,6 +57,7 @@ add_libc_unittest(
SRCS
mktime_test.cpp
HDRS
+ TmHelper.h
TmMatcher.h
DEPENDS
libc.src.time.mktime
diff --git a/libc/test/src/time/TmHelper.h b/libc/test/src/time/TmHelper.h
new file mode 100644
index 0000000000000..6a0b3edac55ea
--- /dev/null
+++ b/libc/test/src/time/TmHelper.h
@@ -0,0 +1,42 @@
+//===---- TmHelper.h ------------------------------------------*- 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_TEST_SRC_TIME_TM_HELPER_H
+#define LLVM_LIBC_TEST_SRC_TIME_TM_HELPER_H
+
+#include <time.h>
+
+#include "src/time/time_utils.h"
+
+using __llvm_libc::time_utils::TimeConstants;
+
+namespace __llvm_libc {
+namespace tmhelper {
+namespace testing {
+
+// A helper function to initialize tm data structure.
+static inline void InitializeTmData(struct tm *tm_data, int year, int month,
+ int mday, int hour, int min, int sec,
+ int wday, int yday) {
+ struct tm temp = {.tm_sec = sec,
+ .tm_min = min,
+ .tm_hour = hour,
+ .tm_mday = mday,
+ .tm_mon = month - 1, // tm_mon starts with 0 for Jan
+ // years since 1900
+ .tm_year = year - TimeConstants::TimeYearBase,
+ .tm_wday = wday,
+ .tm_yday = yday};
+ *tm_data = temp;
+}
+
+} // namespace testing
+} // namespace tmhelper
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_TEST_SRC_TIME_TM_HELPER_H
diff --git a/libc/test/src/time/asctime_r_test.cpp b/libc/test/src/time/asctime_r_test.cpp
new file mode 100644
index 0000000000000..66db4413d3d5d
--- /dev/null
+++ b/libc/test/src/time/asctime_r_test.cpp
@@ -0,0 +1,60 @@
+//===-- Unittests for asctime_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/time/asctime_r.h"
+#include "src/time/time_utils.h"
+#include "test/src/time/TmHelper.h"
+#include "utils/UnitTest/Test.h"
+
+using __llvm_libc::time_utils::TimeConstants;
+
+static inline char *call_asctime_r(struct tm *tm_data, int year, int month,
+ int mday, int hour, int min, int sec,
+ int wday, int yday, char *buffer) {
+ __llvm_libc::tmhelper::testing::InitializeTmData(tm_data, year, month, mday,
+ hour, min, sec, wday, yday);
+ return __llvm_libc::asctime_r(tm_data, buffer);
+}
+
+// asctime and asctime_r share the same code and thus didn't repeat all the
+// tests from asctime. Added couple of validation tests.
+TEST(LlvmLibcAsctimeR, Nullptr) {
+ char *result;
+ result = __llvm_libc::asctime_r(nullptr, nullptr);
+ ASSERT_EQ(EINVAL, llvmlibc_errno);
+ ASSERT_STREQ(nullptr, result);
+
+ char buffer[TimeConstants::AsctimeBufferSize];
+ result = __llvm_libc::asctime_r(nullptr, buffer);
+ ASSERT_EQ(EINVAL, llvmlibc_errno);
+ ASSERT_STREQ(nullptr, result);
+
+ struct tm tm_data;
+ result = __llvm_libc::asctime_r(&tm_data, nullptr);
+ ASSERT_EQ(EINVAL, llvmlibc_errno);
+ ASSERT_STREQ(nullptr, result);
+}
+
+TEST(LlvmLibcAsctimeR, ValidDate) {
+ char buffer[TimeConstants::AsctimeBufferSize];
+ struct tm tm_data;
+ char *result;
+ // 1970-01-01 00:00:00. Test with a valid buffer size.
+ result = call_asctime_r(&tm_data,
+ 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/asctime_test.cpp b/libc/test/src/time/asctime_test.cpp
new file mode 100644
index 0000000000000..14201fd5a0de9
--- /dev/null
+++ b/libc/test/src/time/asctime_test.cpp
@@ -0,0 +1,215 @@
+//===-- Unittests for asctime ---------------------------------------------===//
+//
+// 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/asctime.h"
+#include "test/src/time/TmHelper.h"
+#include "utils/UnitTest/Test.h"
+
+static inline char *call_asctime(struct tm *tm_data, int year, int month,
+ int mday, int hour, int min, int sec, int wday,
+ int yday) {
+ __llvm_libc::tmhelper::testing::InitializeTmData(tm_data, year, month, mday,
+ hour, min, sec, wday, yday);
+ return __llvm_libc::asctime(tm_data);
+}
+
+TEST(LlvmLibcAsctime, Nullptr) {
+ char *result;
+ result = __llvm_libc::asctime(nullptr);
+ ASSERT_EQ(EINVAL, llvmlibc_errno);
+ ASSERT_STREQ(nullptr, result);
+}
+
+// Weekdays are in the range 0 to 6. Test passing invalid value in wday.
+TEST(LlvmLibcAsctime, InvalidWday) {
+ struct tm tm_data;
+ char *result;
+
+ // Test with wday = -1.
+ result = call_asctime(&tm_data,
+ 1970, // year
+ 1, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ -1, // wday
+ 0); // yday
+ ASSERT_EQ(EINVAL, llvmlibc_errno);
+
+ // Test with wday = 7.
+ result = call_asctime(&tm_data,
+ 1970, // year
+ 1, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 7, // wday
+ 0); // yday
+ ASSERT_EQ(EINVAL, llvmlibc_errno);
+}
+
+// Months are from January to December. Test passing invalid value in month.
+TEST(LlvmLibcAsctime, InvalidMonth) {
+ struct tm tm_data;
+ char *result;
+
+ // Test with month = 0.
+ result = call_asctime(&tm_data,
+ 1970, // year
+ 0, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 4, // wday
+ 0); // yday
+ ASSERT_EQ(EINVAL, llvmlibc_errno);
+
+ // Test with month = 13.
+ result = call_asctime(&tm_data,
+ 1970, // year
+ 13, // month
+ 1, // day
+ 0, // hr
+ 0, // min
+ 0, // sec
+ 4, // wday
+ 0); // yday
+ ASSERT_EQ(EINVAL, llvmlibc_errno);
+}
+
+TEST(LlvmLibcAsctime, ValidWeekdays) {
+ struct tm tm_data;
+ char *result;
+ // 1970-01-01 00:00:00.
+ result = call_asctime(&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_asctime(&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_asctime(&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(LlvmLibcAsctime, ValidMonths) {
+ struct tm tm_data;
+ char *result;
+ // 1970-01-01 00:00:00.
+ result = call_asctime(&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_asctime(&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_asctime(&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(LlvmLibcAsctime, 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_asctime(&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(LlvmLibcAsctime, 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_asctime(&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_asctime(&tm_data,
+ 2147483647, // year
+ 1, // month
+ 1, // day
+ 12, // hr
+ 50, // min
+ 50, // sec
+ 2, // wday
+ 50); // yday
+ ASSERT_EQ(EOVERFLOW, llvmlibc_errno);
+ ASSERT_STREQ(nullptr, result);
+}
diff --git a/libc/test/src/time/mktime_test.cpp b/libc/test/src/time/mktime_test.cpp
index 93290d3ec0a4e..b9ea4ed64c0d1 100644
--- a/libc/test/src/time/mktime_test.cpp
+++ b/libc/test/src/time/mktime_test.cpp
@@ -9,6 +9,7 @@
#include "src/time/mktime.h"
#include "src/time/time_utils.h"
#include "test/ErrnoSetterMatcher.h"
+#include "test/src/time/TmHelper.h"
#include "test/src/time/TmMatcher.h"
#include "utils/UnitTest/Test.h"
@@ -20,33 +21,18 @@ using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
using __llvm_libc::time_utils::TimeConstants;
-// A helper function to initialize tm data structure.
-static inline void initialize_tm_data(struct tm *tm_data, int year, int month,
- int mday, int hour, int min, int sec,
- int wday, int yday) {
- struct tm temp = {.tm_sec = sec,
- .tm_min = min,
- .tm_hour = hour,
- .tm_mday = mday,
- .tm_mon = month - 1, // tm_mon starts with 0 for Jan
- // years since 1900
- .tm_year = year - TimeConstants::TimeYearBase,
- .tm_wday = wday,
- .tm_yday = yday};
- *tm_data = temp;
-}
-
static inline time_t call_mktime(struct tm *tm_data, int year, int month,
int mday, int hour, int min, int sec, int wday,
int yday) {
- initialize_tm_data(tm_data, year, month, mday, hour, min, sec, wday, yday);
+ __llvm_libc::tmhelper::testing::InitializeTmData(tm_data, year, month, mday,
+ hour, min, sec, wday, yday);
return __llvm_libc::mktime(tm_data);
}
TEST(LlvmLibcMkTime, FailureSetsErrno) {
struct tm tm_data;
- initialize_tm_data(&tm_data, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, -1,
- 0, 0);
+ __llvm_libc::tmhelper::testing::InitializeTmData(
+ &tm_data, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, -1, 0, 0);
EXPECT_THAT(__llvm_libc::mktime(&tm_data), Fails(EOVERFLOW));
}
More information about the libc-commits
mailing list