Skip to content

Commit e0a4fb4

Browse files
committed
[libc] Add ctime_s
Resolves llvm#110548 Definition: ```c++ int ctime_s(char *buffer, size_t buffer_size, const time_t *t_ptr); ```
1 parent 3ae6b57 commit e0a4fb4

File tree

14 files changed

+197
-0
lines changed

14 files changed

+197
-0
lines changed

libc/config/baremetal/arm/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ set(TARGET_LIBC_ENTRYPOINTS
205205
libc.src.time.asctime_r
206206
libc.src.time.ctime
207207
libc.src.time.ctime_r
208+
libc.src.time.ctime_s
208209
libc.src.time.difftime
209210
libc.src.time.gmtime
210211
libc.src.time.gmtime_r

libc/config/baremetal/riscv/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ set(TARGET_LIBC_ENTRYPOINTS
201201
libc.src.time.asctime_r
202202
libc.src.time.ctime
203203
libc.src.time.ctime_r
204+
libc.src.time.ctime_s
204205
libc.src.time.difftime
205206
libc.src.time.gmtime
206207
libc.src.time.gmtime_r

libc/config/linux/aarch64/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,7 @@ if(LLVM_LIBC_FULL_BUILD)
969969
libc.src.time.asctime_r
970970
libc.src.time.ctime
971971
libc.src.time.ctime_r
972+
libc.src.time.ctime_s
972973
libc.src.time.clock
973974
libc.src.time.clock_gettime
974975
libc.src.time.difftime

libc/config/linux/riscv/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ if(LLVM_LIBC_FULL_BUILD)
901901
libc.src.time.asctime_r
902902
libc.src.time.ctime
903903
libc.src.time.ctime_r
904+
libc.src.time.ctime_s
904905
libc.src.time.clock
905906
libc.src.time.clock_gettime
906907
libc.src.time.difftime

libc/config/linux/x86_64/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,7 @@ if(LLVM_LIBC_FULL_BUILD)
10261026
libc.src.time.asctime_r
10271027
libc.src.time.ctime
10281028
libc.src.time.ctime_r
1029+
libc.src.time.ctime_s
10291030
libc.src.time.clock
10301031
libc.src.time.clock_gettime
10311032
libc.src.time.difftime

libc/docs/date_and_time.rst

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ Implementation Status
5959
+---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+
6060
| ctime_r | |check| | |check| | | |check| | | | | | | | | |
6161
+---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+
62+
| ctime_s | |check| | |check| | | |check| | | | | | | | | |
63+
+---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+
6264
| clock | |check| | |check| | | |check| | | | | | | | | |
6365
+---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+
6466
| clock_getcpuclockid | | | | | | | | | | | | |
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//===-- Definition of rsize_t type ----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_TYPES_RSIZE_T_H
10+
#define LLVM_LIBC_TYPES_RSIZE_T_H
11+
12+
#include <stddef.h>
13+
14+
typedef size_t rsize_t;
15+
16+
#endif // LLVM_LIBC_TYPES_RSIZE_T_H

libc/newhdrgen/yaml/time.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ functions:
3737
arguments:
3838
- type: const time_t *
3939
- type: char *
40+
- name: ctime_s
41+
standard:
42+
- stdc
43+
return_type: int
44+
arguments:
45+
- type: char *
46+
- type: size_t
47+
- type: const time_t *
4048
- name: clock
4149
standard:
4250
- stdc

libc/spec/stdc.td

+9
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,15 @@ def StdC : StandardSpec<"stdc"> {
16301630
ArgSpec<CharPtr>,
16311631
]
16321632
>,
1633+
FunctionSpec<
1634+
"ctime_s",
1635+
RetValSpec<IntType>,
1636+
[
1637+
ArgSpec<CharPtr>,
1638+
ArgSpec<SizeTType>,
1639+
ArgSpec<ConstTimeTTypePtr>,
1640+
]
1641+
>,
16331642
FunctionSpec<
16341643
"clock",
16351644
RetValSpec<ClockT>,

libc/src/time/CMakeLists.txt

+12
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ add_entrypoint_object(
6060
libc.include.time
6161
)
6262

63+
add_entrypoint_object(
64+
ctime_s
65+
SRCS
66+
ctime_s.cpp
67+
HDRS
68+
ctime_s.h
69+
DEPENDS
70+
.time_utils
71+
libc.hdr.types.time_t
72+
libc.include.time
73+
)
74+
6375
add_entrypoint_object(
6476
difftime
6577
SRCS

libc/src/time/ctime_s.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===-- Implementation of ctime_s function --------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "ctime_s.h"
10+
#include "hdr/errno_macros.h"
11+
#include "src/__support/CPP/limits.h"
12+
#include "src/__support/common.h"
13+
#include "src/__support/macros/config.h"
14+
#include "time_utils.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
using LIBC_NAMESPACE::time_utils::TimeConstants;
19+
20+
LLVM_LIBC_FUNCTION(int, ctime_s,
21+
(char *buffer, rsize_t buffer_size, const time_t *t_ptr)) {
22+
if (t_ptr == nullptr || buffer == nullptr ||
23+
*t_ptr > cpp::numeric_limits<int32_t>::max()) {
24+
if (buffer != nullptr)
25+
buffer[0] = '\0';
26+
return EINVAL;
27+
}
28+
29+
if (buffer_size < TimeConstants::ASCTIME_MAX_BYTES) {
30+
buffer[0] = '\0';
31+
return ERANGE;
32+
}
33+
34+
if (time_utils::asctime(time_utils::localtime(t_ptr), buffer, buffer_size) ==
35+
nullptr) {
36+
buffer[0] = '\0';
37+
return EINVAL;
38+
}
39+
40+
return 0;
41+
}
42+
43+
} // namespace LIBC_NAMESPACE_DECL

libc/src/time/ctime_s.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation header of ctime_s ------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_TIME_CTIME_S_H
10+
#define LLVM_LIBC_SRC_TIME_CTIME_S_H
11+
12+
#include "hdr/types/time_t.h"
13+
#include "include/llvm-libc-types/rsize_t.h"
14+
#include "src/__support/macros/config.h"
15+
#include <stddef.h>
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
int ctime_s(char *buffer, rsize_t buffer_size, const time_t *t_ptr);
20+
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SRC_TIME_CTIME_S_H

libc/test/src/time/CMakeLists.txt

+18
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,24 @@ add_libc_unittest(
6666
libc.src.time.time_utils
6767
)
6868

69+
add_libc_unittest(
70+
ctime_s_test
71+
SUITE
72+
libc_time_unittests
73+
SRCS
74+
ctime_s_test.cpp
75+
HDRS
76+
TmHelper.h
77+
TmMatcher.h
78+
CXX_STANDARD
79+
20
80+
DEPENDS
81+
libc.include.time
82+
libc.hdr.types.time_t
83+
libc.src.time.ctime_s
84+
libc.src.time.time_utils
85+
)
86+
6987
add_libc_test(
7088
clock_gettime_test
7189
SUITE

libc/test/src/time/ctime_s_test.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===-- Unittests for ctime_s ---------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "hdr/errno_macros.h"
10+
#include "src/errno/libc_errno.h"
11+
#include "src/time/ctime_s.h"
12+
#include "src/time/time_utils.h"
13+
#include "test/UnitTest/Test.h"
14+
#include "test/src/time/TmHelper.h"
15+
16+
using LIBC_NAMESPACE::time_utils::TimeConstants;
17+
18+
TEST(LlvmLibcCtimeS, Nullptr) {
19+
int result;
20+
result = LIBC_NAMESPACE::ctime_s(nullptr, 0, nullptr);
21+
ASSERT_EQ(EINVAL, result);
22+
23+
char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
24+
result = LIBC_NAMESPACE::ctime_s(buffer, sizeof(buffer), nullptr);
25+
ASSERT_EQ(EINVAL, result);
26+
27+
time_t t;
28+
result = LIBC_NAMESPACE::ctime_s(nullptr, 0, &t);
29+
ASSERT_EQ(EINVAL, result);
30+
}
31+
32+
TEST(LlvmLibcCtimeS, ValidUnixTimestamp0) {
33+
char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
34+
time_t t;
35+
int result;
36+
// 1970-01-01 00:00:00. Test with a valid buffer size.
37+
t = 0;
38+
result = LIBC_NAMESPACE::ctime_s(buffer, sizeof(buffer), &t);
39+
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", buffer);
40+
ASSERT_EQ(0, result);
41+
}
42+
43+
TEST(LlvmLibcCtimeS, ValidUnixTimestamp32Int) {
44+
char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
45+
time_t t;
46+
int result;
47+
// 2038-01-19 03:14:07. Test with a valid buffer size.
48+
t = 2147483647;
49+
result = LIBC_NAMESPACE::ctime_s(buffer, sizeof(buffer), &t);
50+
ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", buffer);
51+
ASSERT_EQ(0, result);
52+
}
53+
54+
TEST(LlvmLibcCtimeS, InvalidArgument) {
55+
char buffer[TimeConstants::ASCTIME_BUFFER_SIZE];
56+
time_t t;
57+
int result;
58+
t = 2147483648;
59+
result = LIBC_NAMESPACE::ctime_s(buffer, sizeof(buffer), &t);
60+
ASSERT_EQ(EINVAL, result);
61+
}

0 commit comments

Comments
 (0)