Skip to content

Commit b00a698

Browse files
committed
[libc] Implement strftime
1 parent 8ea3b4c commit b00a698

File tree

17 files changed

+159
-152
lines changed

17 files changed

+159
-152
lines changed

libc/src/stdio/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,6 @@ add_entrypoint_object(
239239

240240
add_subdirectory(printf_core)
241241
add_subdirectory(scanf_core)
242-
add_subdirectory(strftime_core)
243242

244243
add_entrypoint_object(
245244
remove

libc/src/stdio/strftime_core/CMakeLists.txt

Lines changed: 0 additions & 52 deletions
This file was deleted.

libc/src/time/CMakeLists.txt

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -103,28 +103,6 @@ add_entrypoint_object(
103103
libc.src.errno.errno
104104
)
105105

106-
107-
add_entrypoint_object(
108-
strftime
109-
SRCS
110-
strftime.cpp
111-
HDRS
112-
strftime.h
113-
DEPENDS
114-
libc.include.time
115-
)
116-
117-
add_entrypoint_object(
118-
strftime_l
119-
SRCS
120-
strftime_l.cpp
121-
HDRS
122-
strftime_l.h
123-
DEPENDS
124-
libc.include.time
125-
libc.include.locale
126-
)
127-
128106
add_entrypoint_object(
129107
time
130108
ALIAS
@@ -159,3 +137,30 @@ add_entrypoint_object(
159137
DEPENDS
160138
.${LIBC_TARGET_OS}.gettimeofday
161139
)
140+
141+
add_subdirectory(strftime_core)
142+
143+
add_entrypoint_object(
144+
strftime
145+
SRCS
146+
strftime.cpp
147+
HDRS
148+
strftime.h
149+
DEPENDS
150+
libc.include.time
151+
libc.src.time.strftime_core.strftime_main
152+
libc.src.stdio.printf_core.writer
153+
)
154+
155+
add_entrypoint_object(
156+
strftime_l
157+
SRCS
158+
strftime_l.cpp
159+
HDRS
160+
strftime_l.h
161+
DEPENDS
162+
libc.include.time
163+
libc.include.locale
164+
libc.src.time.strftime_core.strftime_main
165+
libc.src.stdio.printf_core.writer
166+
)

libc/src/time/strftime.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@
1212
#include "src/errno/libc_errno.h"
1313
#include "src/time/time_utils.h"
1414

15+
#include "src/stdio/printf_core/writer.h"
16+
#include "src/time/strftime_core/strftime_main.h"
1517
namespace LIBC_NAMESPACE_DECL {
1618

17-
using LIBC_NAMESPACE::time_utils::TimeConstants;
19+
size_t strftime(char *__restrict buffer, size_t buffsz, const char *__restrict format,
20+
const struct tm *timeptr) {
1821

19-
LLVM_LIBC_FUNCTION(size_t, strftime,
20-
(char *__restrict, size_t, const char *__restrict,
21-
const struct tm *)) {
22-
// TODO: Implement this for the default locale.
22+
printf_core::WriteBuffer wb(buffer, (buffsz > 0 ? buffsz - 1 : 0));
23+
printf_core::Writer writer(&wb);
24+
strftime_core::strftime_main(&writer, format, timeptr);
2325
return -1;
2426
}
2527

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
add_header_library(
3+
core_structs
4+
HDRS
5+
core_structs.h
6+
DEPENDS
7+
libc.src.__support.CPP.string_view
8+
)
9+
10+
add_header_library(
11+
parser
12+
HDRS
13+
parser.h
14+
)
15+
16+
add_object_library(
17+
converter
18+
SRCS
19+
converter.cpp
20+
HDRS
21+
converter.h
22+
DEPENDS
23+
.core_structs
24+
.parser
25+
libc.src.stdio.printf_core.writer
26+
libc.src.__support.big_int
27+
libc.src.math.log10
28+
libc.src.__support.CPP.string_view
29+
libc.src.__support.float_to_string
30+
libc.src.__support.integer_to_string
31+
libc.src.__support.uint128
32+
libc.src.__support.StringUtil.error_to_string
33+
)
34+
35+
add_object_library(
36+
strftime_main
37+
SRCS
38+
strftime_main.cpp
39+
HDRS
40+
strftime_main.h
41+
DEPENDS
42+
.core_structs
43+
.parser
44+
.converter
45+
libc.src.stdio.printf_core.writer
46+
)

libc/src/stdio/strftime_core/converter.cpp renamed to libc/src/time/strftime_core/converter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
#include "src/__support/macros/config.h"
1616
#include "src/math/log10.h"
1717
#include "src/stdio/printf_core/writer.h"
18-
#include "src/stdio/strftime_core/core_structs.h"
19-
#include "src/stdio/strftime_core/time_internal_def.h"
18+
#include "src/time/strftime_core/core_structs.h"
19+
#include "src/time/strftime_core/time_internal_def.h"
2020
#include <time.h>
2121

2222
namespace LIBC_NAMESPACE_DECL {

libc/src/stdio/strftime_core/converter.h renamed to libc/src/time/strftime_core/converter.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
#ifndef LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CONVERTER_H
1010
#define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CONVERTER_H
1111

12-
#include "src/__support/macros/config.h"
1312
#include "src/stdio/printf_core/writer.h"
14-
#include "src/stdio/strftime_core/core_structs.h"
13+
#include "src/time/strftime_core/core_structs.h"
1514

1615
#include <stddef.h>
1716

libc/src/stdio/strftime_core/core_structs.h renamed to libc/src/time/strftime_core/core_structs.h

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,7 @@
99
#ifndef LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CORE_STRUCTS_H
1010
#define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CORE_STRUCTS_H
1111

12-
#include "src/__support/macros/config.h"
13-
1412
#include "src/__support/CPP/string_view.h"
15-
#include "src/__support/CPP/type_traits.h"
16-
#include "src/__support/FPUtil/FPBits.h"
17-
18-
#include <inttypes.h>
19-
#include <stddef.h>
2013

2114
namespace LIBC_NAMESPACE_DECL {
2215
namespace strftime_core {
@@ -44,43 +37,6 @@ struct FormatSection {
4437
const struct tm *time;
4538
};
4639

47-
enum PrimaryType : uint8_t {
48-
Unknown = 0,
49-
Float = 1,
50-
Pointer = 2,
51-
Integer = 3,
52-
FixedPoint = 4,
53-
};
54-
55-
// TypeDesc stores the information about a type that is relevant to printf in
56-
// a relatively compact manner.
57-
struct TypeDesc {
58-
uint8_t size;
59-
PrimaryType primary_type;
60-
LIBC_INLINE constexpr bool operator==(const TypeDesc &other) const {
61-
return (size == other.size) && (primary_type == other.primary_type);
62-
}
63-
};
64-
65-
template <typename T> LIBC_INLINE constexpr TypeDesc type_desc_from_type() {
66-
if constexpr (cpp::is_same_v<T, void>) {
67-
return TypeDesc{0, PrimaryType::Unknown};
68-
} else {
69-
constexpr bool IS_POINTER = cpp::is_pointer_v<T>;
70-
constexpr bool IS_FLOAT = cpp::is_floating_point_v<T>;
71-
#ifdef LIBC_INTERNAL_STRFTIME_HAS_FIXED_POINT
72-
constexpr bool IS_FIXED_POINT = cpp::is_fixed_point_v<T>;
73-
#else
74-
constexpr bool IS_FIXED_POINT = false;
75-
#endif // LIBC_INTERNAL_STRFTIME_HAS_FIXED_POINT
76-
77-
return TypeDesc{sizeof(T), IS_POINTER ? PrimaryType::Pointer
78-
: IS_FLOAT ? PrimaryType::Float
79-
: IS_FIXED_POINT ? PrimaryType::FixedPoint
80-
: PrimaryType::Integer};
81-
}
82-
}
83-
8440
// This is the value to be returned by conversions when no error has occurred.
8541
constexpr int WRITE_OK = 0;
8642
// These are the printf return values for when an error has occurred. They are

libc/src/stdio/strftime_core/parser.h renamed to libc/src/time/strftime_core/parser.h

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,7 @@
99
#ifndef LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_PARSER_H
1010
#define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_PARSER_H
1111

12-
#include "include/llvm-libc-macros/stdfix-macros.h"
13-
#include "src/__support/CPP/algorithm.h" // max
14-
#include "src/__support/CPP/limits.h"
15-
#include "src/__support/CPP/optional.h"
16-
#include "src/__support/CPP/type_traits.h"
17-
#include "src/__support/macros/config.h"
18-
#include "src/__support/str_to_integer.h"
19-
#include "src/stdio/strftime_core/core_structs.h"
20-
// #include "src/stdio/strftime_core/printf_config.h"
21-
22-
#include <stddef.h>
23-
24-
#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
25-
#include "src/__support/fixed_point/fx_rep.h"
26-
#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
27-
#ifndef LIBC_COPT_PRINTF_DISABLE_STRERROR
28-
#include "src/errno/libc_errno.h"
29-
#endif // LIBC_COPT_PRINTF_DISABLE_STRERROR
12+
#include <time.h>
3013

3114
namespace LIBC_NAMESPACE_DECL {
3215
namespace strftime_core {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//===-- Starting point for strftime -------------------------------*- C++
2+
//-*-===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "src/time/strftime_core/strftime_main.h"
11+
12+
#include "src/stdio/printf_core/writer.h"
13+
#include "src/time/strftime_core/converter.h"
14+
#include "src/time/strftime_core/core_structs.h"
15+
#include "src/time/strftime_core/parser.h"
16+
17+
#include <stddef.h>
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
namespace strftime_core {
21+
22+
int strftime_main(Writer *writer, const char *__restrict str,
23+
const struct tm *timeptr) {
24+
Parser parser(str, timeptr);
25+
int result = 0;
26+
for (FormatSection cur_section = parser.get_next_section();
27+
!cur_section.raw_string.empty();
28+
cur_section = parser.get_next_section()) {
29+
if (cur_section.has_conv)
30+
result = convert(writer, cur_section);
31+
else
32+
result = writer->write(cur_section.raw_string);
33+
34+
if (result < 0)
35+
return result;
36+
}
37+
38+
return writer->get_chars_written();
39+
}
40+
41+
} // namespace strftime_core
42+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- Starting point for strftime -------------------------------*- 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_STDIO_STRFTIME_CORE_STRFTIME_MAIN_H
10+
#define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_STRFTIME_MAIN_H
11+
12+
#include "src/__support/macros/config.h"
13+
#include "src/stdio/printf_core/writer.h"
14+
15+
#include <stddef.h>
16+
#include <time.h>
17+
18+
namespace LIBC_NAMESPACE_DECL {
19+
namespace strftime_core {
20+
21+
int strftime_main(printf_core::Writer *writer, const char *__restrict str, const struct tm *timeptr);
22+
23+
} // namespace strftime_core
24+
} // namespace LIBC_NAMESPACE_DECL
25+
26+
#endif // LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_STRFTIME_MAIN_H

libc/test/src/stdio/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,5 +542,4 @@ endif()
542542

543543
add_subdirectory(printf_core)
544544
add_subdirectory(scanf_core)
545-
add_subdirectory(strftime_core)
546545
add_subdirectory(testdata)

libc/test/src/time/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,5 @@ add_libc_test(
173173
libc.src.time.clock
174174
libc.src.errno.errno
175175
)
176+
177+
add_subdirectory(strftime_core)
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
add_libc_unittest(
22
converter_test
33
SUITE
4-
libc_stdio_unittests
4+
libc_time_unittests
55
SRCS
66
converter_test.cpp
77
DEPENDS
8-
libc.src.stdio.strftime_core.converter
8+
libc.src.time.strftime_core.converter
99
libc.src.stdio.printf_core.writer
10-
libc.src.stdio.strftime_core.core_structs
10+
libc.src.time.strftime_core.core_structs
1111
)

0 commit comments

Comments
 (0)