Skip to content

Commit 6de62aa

Browse files
committed
[libc] Implement strfromd() and strfroml()
1 parent 34f0a8a commit 6de62aa

File tree

12 files changed

+608
-47
lines changed

12 files changed

+608
-47
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ set(TARGET_LIBC_ENTRYPOINTS
180180
libc.src.stdlib.qsort_r
181181
libc.src.stdlib.rand
182182
libc.src.stdlib.srand
183+
libc.src.stdlib.strfromd
183184
libc.src.stdlib.strfromf
185+
libc.src.stdlib.strfroml
184186
libc.src.stdlib.strtod
185187
libc.src.stdlib.strtof
186188
libc.src.stdlib.strtol

libc/spec/stdc.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,9 @@ def StdC : StandardSpec<"stdc"> {
956956
FunctionSpec<"rand", RetValSpec<IntType>, [ArgSpec<VoidType>]>,
957957
FunctionSpec<"srand", RetValSpec<VoidType>, [ArgSpec<UnsignedIntType>]>,
958958

959+
FunctionSpec<"strfromd", RetValSpec<IntType>, [ArgSpec<CharRestrictedPtr>, ArgSpec<SizeTType>, ArgSpec<ConstCharRestrictedPtr>, ArgSpec<DoubleType>]>,
959960
FunctionSpec<"strfromf", RetValSpec<IntType>, [ArgSpec<CharRestrictedPtr>, ArgSpec<SizeTType>, ArgSpec<ConstCharRestrictedPtr>, ArgSpec<FloatType>]>,
961+
FunctionSpec<"strfroml", RetValSpec<IntType>, [ArgSpec<CharRestrictedPtr>, ArgSpec<SizeTType>, ArgSpec<ConstCharRestrictedPtr>, ArgSpec<LongDoubleType>]>,
960962

961963
FunctionSpec<"strtof", RetValSpec<FloatType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>]>,
962964
FunctionSpec<"strtod", RetValSpec<DoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>]>,

libc/src/stdlib/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,26 @@ add_entrypoint_object(
6262
.str_from_util
6363
)
6464

65+
add_entrypoint_object(
66+
strfromd
67+
SRCS
68+
strfromd.cpp
69+
HDRS
70+
strfromd.h
71+
DEPENDS
72+
.str_from_util
73+
)
74+
75+
add_entrypoint_object(
76+
strfroml
77+
SRCS
78+
strfroml.cpp
79+
HDRS
80+
strfroml.h
81+
DEPENDS
82+
.str_from_util
83+
)
84+
6585
add_header_library(
6686
str_from_util
6787
HDRS

libc/src/stdlib/strfromd.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//===-- Implementation of strfromd ------------------------------*- 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+
#include "src/stdlib/strfromd.h"
10+
#include "src/stdlib/str_from_util.h"
11+
12+
#include <stdarg.h>
13+
#include <stddef.h>
14+
15+
namespace LIBC_NAMESPACE {
16+
17+
LLVM_LIBC_FUNCTION(int, strfromd,
18+
(char *__restrict s, size_t n, const char *__restrict format,
19+
double fp)) {
20+
LIBC_ASSERT(s != nullptr);
21+
22+
printf_core::FormatSection section =
23+
internal::parse_format_string(format, fp);
24+
printf_core::WriteBuffer wb(s, (n > 0 ? n - 1 : 0));
25+
printf_core::Writer writer(&wb);
26+
27+
int result = 0;
28+
if (section.has_conv)
29+
result = internal::strfromfloat_convert<double>(&writer, section);
30+
else
31+
result = writer.write(section.raw_string);
32+
33+
if (result < 0)
34+
return result;
35+
36+
if (n > 0)
37+
wb.buff[wb.buff_cur] = '\0';
38+
39+
return writer.get_chars_written();
40+
}
41+
42+
} // namespace LIBC_NAMESPACE

libc/src/stdlib/strfromd.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for strfromd ------------------------*- 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_STDLIB_STRFROMD_H
10+
#define LLVM_LIBC_SRC_STDLIB_STRFROMD_H
11+
12+
#include <stddef.h>
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
int strfromd(char *__restrict s, size_t n, const char *__restrict format,
17+
double fp);
18+
19+
} // namespace LIBC_NAMESPACE
20+
21+
#endif // LLVM_LIBC_SRC_STDLIB_STRFROMD_H

libc/src/stdlib/strfromf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ int strfromf(char *__restrict s, size_t n, const char *__restrict format,
1818

1919
} // namespace LIBC_NAMESPACE
2020

21-
#endif // LLVM_LIBC_SRC_STDLIB_STRTOF_H
21+
#endif // LLVM_LIBC_SRC_STDLIB_STRFROMF_H

libc/src/stdlib/strfroml.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===-- Implementation of strfroml ------------------------------*- 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+
#include "src/stdlib/strfroml.h"
10+
#include "src/stdlib/str_from_util.h"
11+
12+
#include <stdarg.h>
13+
#include <stddef.h>
14+
15+
namespace LIBC_NAMESPACE {
16+
17+
LLVM_LIBC_FUNCTION(int, strfroml,
18+
(char *__restrict s, size_t n, const char *__restrict format,
19+
long double fp)) {
20+
LIBC_ASSERT(s != nullptr);
21+
22+
printf_core::FormatSection section =
23+
internal::parse_format_string(format, fp);
24+
section.length_modifier = printf_core::LengthModifier::L;
25+
26+
printf_core::WriteBuffer wb(s, (n > 0 ? n - 1 : 0));
27+
printf_core::Writer writer(&wb);
28+
29+
int result = 0;
30+
if (section.has_conv)
31+
result = internal::strfromfloat_convert<long double>(&writer, section);
32+
else
33+
result = writer.write(section.raw_string);
34+
35+
if (result < 0)
36+
return result;
37+
38+
if (n > 0)
39+
wb.buff[wb.buff_cur] = '\0';
40+
41+
return writer.get_chars_written();
42+
}
43+
44+
} // namespace LIBC_NAMESPACE

libc/src/stdlib/strfroml.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
//===-- Implementation header for strfroml ------------------------*- C++--===//
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+
#ifndef LLVM_LIBC_SRC_STDLIB_STRFROML_H
11+
#define LLVM_LIBC_SRC_STDLIB_STRFROML_H
12+
13+
#include <stddef.h>
14+
15+
namespace LIBC_NAMESPACE {
16+
17+
int strfroml(char *__restrict s, size_t n, const char *__restrict format,
18+
long double fp);
19+
20+
} // namespace LIBC_NAMESPACE
21+
22+
#endif // LLVM_LIBC_SRC_STDLIB_STRFROML_H

libc/test/src/stdlib/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,26 @@ add_libc_test(
178178
libc.src.stdlib.strfromf
179179
)
180180

181+
add_libc_test(
182+
strfromd_test
183+
SUITE
184+
libc-stdlib-tests
185+
SRCS
186+
strfromd_test.cpp
187+
DEPENDS
188+
libc.src.stdlib.strfromd
189+
)
190+
191+
add_libc_test(
192+
strfroml_test
193+
SUITE
194+
libc-stdlib-tests
195+
SRCS
196+
strfroml_test.cpp
197+
DEPENDS
198+
libc.src.stdlib.strfroml
199+
)
200+
181201
add_libc_test(
182202
abs_test
183203
SUITE

0 commit comments

Comments
 (0)