Skip to content

Commit c4f5728

Browse files
committed
[libc] Refactor converter.cpp
1 parent 097d459 commit c4f5728

File tree

12 files changed

+522
-366
lines changed

12 files changed

+522
-366
lines changed

libc/src/time/strftime.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ namespace LIBC_NAMESPACE_DECL {
1919
size_t strftime(char *__restrict buffer, size_t buffsz,
2020
const char *__restrict format, const struct tm *timeptr) {
2121

22-
printf_core::WriteBuffer wb(buffer, (buffsz > 0 ? buffsz - 1 : 0));
22+
printf_core::WriteBuffer wb(buffer, (buffsz > 0 ? buffsz - 1 : 0),
23+
strftime_core::overflow_write_mock, nullptr);
2324
printf_core::Writer writer(&wb);
24-
strftime_core::strftime_main(&writer, format, timeptr);
25-
return writer.get_chars_written();
25+
int ret = strftime_core::strftime_main(&writer, format, timeptr);
26+
if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
27+
wb.buff[wb.buff_cur] = '\0';
28+
return ret > 0 ? ret : 0;
2629
}
2730

2831
} // namespace LIBC_NAMESPACE_DECL

libc/src/time/strftime_core/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ add_object_library(
2424
converter.cpp
2525
HDRS
2626
converter.h
27+
num_converter.h
28+
str_converter.h
29+
composite_converter.h
2730
DEPENDS
2831
.core_structs
32+
libc.src.__support.arg_list
2933
libc.src.stdio.printf_core.writer
34+
libc.src.stdio.printf_core.printf_main
3035
libc.src.__support.big_int
3136
libc.src.__support.CPP.string_view
3237
libc.src.__support.float_to_string
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//===-- Format specifier converter for printf -------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See htto_conv.times://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_COMPOSITE_CONVERTER_H
10+
#define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_COMPOSITE_CONVERTER_H
11+
12+
#include "src/__support/CPP/string_view.h"
13+
#include "src/__support/arg_list.h"
14+
#include "src/__support/integer_to_string.h"
15+
#include "src/__support/macros/config.h"
16+
#include "src/stdio/printf_core/printf_main.h"
17+
#include "src/stdio/printf_core/writer.h"
18+
#include "src/time/strftime_core/core_structs.h"
19+
#include "src/time/strftime_core/time_internal_def.h"
20+
21+
namespace LIBC_NAMESPACE_DECL {
22+
namespace strftime_core {
23+
24+
namespace details {
25+
int snprintf_impl(char *__restrict buffer, size_t buffsz,
26+
const char *__restrict format, ...) {
27+
va_list vlist;
28+
va_start(vlist, format);
29+
internal::ArgList args(vlist);
30+
va_end(vlist);
31+
printf_core::WriteBuffer wb(buffer, (buffsz > 0 ? buffsz - 1 : 0));
32+
printf_core::Writer writer(&wb);
33+
34+
int ret_val = printf_core::printf_main(&writer, format, args);
35+
if (buffsz > 0)
36+
wb.buff[wb.buff_cur] = '\0';
37+
return ret_val;
38+
}
39+
} // namespace details
40+
41+
int write_composite(printf_core::Writer *writer, const FormatSection &to_conv) {
42+
char buffer[100];
43+
auto &time = *to_conv.time;
44+
45+
switch (to_conv.conv_name) {
46+
// Full date and time representation (e.g., equivalent to %a %b %e %T %Y)
47+
case 'c': {
48+
RET_IF_RESULT_NEGATIVE(details::snprintf_impl(
49+
buffer, sizeof(buffer), "%s %s %02d %02d:%02d:%02d %d",
50+
safe_abbreviated_day_name(time.tm_wday),
51+
safe_abbreviated_month_name(time.tm_mon), time.tm_mday, time.tm_hour,
52+
time.tm_min, time.tm_sec, time.tm_year + 1900));
53+
break;
54+
}
55+
56+
// Zero-padded day of the month (equivalent to %m/%d/%y)
57+
case 'D': {
58+
RET_IF_RESULT_NEGATIVE(details::snprintf_impl(
59+
buffer, sizeof(buffer), "%02d/%02d/%02d", time.tm_mon + 1, time.tm_mday,
60+
(time.tm_year + 1900) % 100));
61+
break;
62+
}
63+
64+
// ISO 8601 date representation in YYYY-MM-DD (equivalent to %Y-%m-%d)
65+
case 'F': {
66+
RET_IF_RESULT_NEGATIVE(details::snprintf_impl(
67+
buffer, sizeof(buffer), "%04d-%02d-%02d", time.tm_year + 1900,
68+
time.tm_mon + 1, time.tm_mday));
69+
break;
70+
}
71+
72+
// 12-hour clock time with seconds and AM/PM (equivalent to %I:%M:%S %p)
73+
case 'r': {
74+
int hour12 = time.tm_hour % 12;
75+
if (hour12 == 0)
76+
hour12 = 12;
77+
RET_IF_RESULT_NEGATIVE(details::snprintf_impl(
78+
buffer, sizeof(buffer), "%02d:%02d:%02d %s", hour12, time.tm_min,
79+
time.tm_sec,
80+
to_conv.time->tm_hour >= 12 ? default_PM_str : default_AM_str));
81+
break;
82+
}
83+
84+
// 24-hour time without seconds (equivalent to %H:%M)
85+
case 'R': {
86+
RET_IF_RESULT_NEGATIVE(details::snprintf_impl(
87+
buffer, sizeof(buffer), "%02d:%02d", time.tm_hour, time.tm_min));
88+
break;
89+
}
90+
91+
// Time with seconds (equivalent to %H:%M:%S)
92+
case 'T': {
93+
RET_IF_RESULT_NEGATIVE(
94+
details::snprintf_impl(buffer, sizeof(buffer), "%02d:%02d:%02d",
95+
time.tm_hour, time.tm_min, time.tm_sec));
96+
break;
97+
}
98+
99+
// Locale's date representation (often equivalent to %m/%d/%y)
100+
case 'x': {
101+
RET_IF_RESULT_NEGATIVE(details::snprintf_impl(
102+
buffer, sizeof(buffer), "%02d/%02d/%02d", time.tm_mon + 1, time.tm_mday,
103+
(time.tm_year + 1900) % 100));
104+
break;
105+
}
106+
107+
// Locale's time representation (equivalent to %H:%M:%S)
108+
case 'X': {
109+
RET_IF_RESULT_NEGATIVE(
110+
details::snprintf_impl(buffer, sizeof(buffer), "%02d:%02d:%02d",
111+
time.tm_hour, time.tm_min, time.tm_sec));
112+
break;
113+
}
114+
115+
default:
116+
return writer->write(to_conv.raw_string);
117+
}
118+
return writer->write(buffer);
119+
}
120+
121+
} // namespace strftime_core
122+
} // namespace LIBC_NAMESPACE_DECL
123+
124+
#endif

0 commit comments

Comments
 (0)