Skip to content

Commit 16f0462

Browse files
sribee8Sriya Pratipati
andauthored
[libc] wcslcpy implementation (#146571)
Implemented wcslcpy and tests. --------- Co-authored-by: Sriya Pratipati <sriyap@google.com>
1 parent 9d8058e commit 16f0462

File tree

9 files changed

+174
-0
lines changed

9 files changed

+174
-0
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ set(TARGET_LIBC_ENTRYPOINTS
385385
libc.src.wchar.wcsstr
386386
libc.src.wchar.wcsncat
387387
libc.src.wchar.wcscpy
388+
libc.src.wchar.wcslcpy
388389
libc.src.wchar.wmemchr
389390
libc.src.wchar.wcpcpy
390391
libc.src.wchar.wcpncpy

libc/include/wchar.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ functions:
203203
arguments:
204204
- type: wchar_t *__restrict
205205
- type: const wchar_t *__restrict
206+
- name: wcslcpy
207+
standards:
208+
- stdc
209+
return_type: size_t
210+
arguments:
211+
- type: wchar_t *__restrict
212+
- type: const wchar_t *__restrict
213+
- type: size_t
206214
- name: wcstok
207215
standards:
208216
- stdc

libc/src/wchar/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,14 @@ add_entrypoint_object(
340340
libc.hdr.wchar_macros
341341
libc.src.string.string_utils
342342
)
343+
344+
add_entrypoint_object(
345+
wcslcpy
346+
SRCS
347+
wcslcpy.cpp
348+
HDRS
349+
wcslcpy.h
350+
DEPENDS
351+
libc.hdr.types.size_t
352+
libc.hdr.wchar_macros
353+
)

libc/src/wchar/wcslcpy.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===-- Implementation of wcslcpy -----------------------------------------===//
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/wchar/wcslcpy.h"
10+
11+
#include "hdr/types/size_t.h"
12+
#include "hdr/types/wchar_t.h"
13+
#include "src/__support/common.h"
14+
#include "src/__support/macros/config.h"
15+
#include "src/string/string_utils.h"
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
LLVM_LIBC_FUNCTION(size_t, wcslcpy,
20+
(wchar_t *__restrict dst, const wchar_t *__restrict src,
21+
size_t dstsize)) {
22+
size_t len = internal::string_length(src);
23+
if (dstsize == 0)
24+
return len;
25+
size_t i = 0;
26+
for (; i < dstsize - 1 && src[i] != L'\0'; ++i)
27+
dst[i] = src[i];
28+
dst[i] = L'\0';
29+
return len;
30+
}
31+
32+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcslcpy.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation header for wcslcpy ---------------------------------===//
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_WCHAR_WCSLCPY_H
10+
#define LLVM_LIBC_SRC_WCHAR_WCSLCPY_H
11+
12+
#include "hdr/types/size_t.h"
13+
#include "hdr/types/wchar_t.h"
14+
#include "src/__support/macros/config.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
size_t wcslcpy(wchar_t *__restrict dst, const wchar_t *__restrict src,
19+
size_t dstsize);
20+
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SRC_WCHAR_WCSLCPY_H

libc/test/src/wchar/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,17 @@ add_libc_test(
303303
libc.src.wchar.wcpcpy
304304
)
305305

306+
add_libc_test(
307+
wcslcpy_test
308+
SUITE
309+
libc_wchar_unittests
310+
SRCS
311+
wcslcpy_test.cpp
312+
DEPENDS
313+
libc.hdr.types.size_t
314+
libc.src.wchar.wcslcpy
315+
)
316+
306317
add_libc_test(
307318
wcpncpy_test
308319
SUITE

libc/test/src/wchar/wcslcpy_test.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//===-- Unittests for wcslcpy ---------------------------------------------===//
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/types/size_t.h"
10+
#include "hdr/types/wchar_t.h"
11+
#include "src/wchar/wcslcpy.h"
12+
#include "test/UnitTest/Test.h"
13+
14+
TEST(LlvmLibcWCSLCpyTest, BiggerSource) {
15+
const wchar_t *src = L"abcde";
16+
wchar_t dst[3];
17+
size_t res = LIBC_NAMESPACE::wcslcpy(dst, src, 3);
18+
ASSERT_TRUE(dst[0] == L'a');
19+
ASSERT_TRUE(dst[1] == L'b');
20+
// Should append null terminator
21+
ASSERT_TRUE(dst[2] == L'\0');
22+
// Should still return length of src
23+
ASSERT_EQ(res, size_t(5));
24+
}
25+
26+
TEST(LlvmLibcWCSLCpyTest, CopyZero) {
27+
const wchar_t *src = L"abcde";
28+
wchar_t dst = L'f';
29+
// Copying zero should not change destination
30+
size_t res = LIBC_NAMESPACE::wcslcpy(&dst, src, 0);
31+
ASSERT_TRUE(dst == L'f');
32+
// Should still return length of src
33+
ASSERT_EQ(res, size_t(5));
34+
}
35+
36+
TEST(LlvmLibcWCSLCpyTest, SmallerSource) {
37+
const wchar_t *src = L"abc";
38+
wchar_t dst[7]{L"123456"};
39+
size_t res = LIBC_NAMESPACE::wcslcpy(dst, src, 7);
40+
ASSERT_TRUE(dst[0] == L'a');
41+
ASSERT_TRUE(dst[1] == L'b');
42+
ASSERT_TRUE(dst[2] == L'c');
43+
// Should append null terminator after copying source
44+
ASSERT_TRUE(dst[3] == L'\0');
45+
// Should not change following characters
46+
ASSERT_TRUE(dst[4] == L'5');
47+
ASSERT_TRUE(dst[5] == L'6');
48+
ASSERT_TRUE(dst[6] == L'\0');
49+
// Should still return length of src
50+
ASSERT_EQ(res, size_t(3));
51+
}
52+
53+
TEST(LlvmLibcWCSLCpyTest, DoesNotCopyAfterNull) {
54+
const wchar_t src[5] = {L'a', L'b', L'\0', L'c', L'd'};
55+
wchar_t dst[5]{L"1234"};
56+
size_t res = LIBC_NAMESPACE::wcslcpy(dst, src, 5);
57+
ASSERT_TRUE(dst[0] == L'a');
58+
ASSERT_TRUE(dst[1] == L'b');
59+
ASSERT_TRUE(dst[2] == L'\0');
60+
// Should not change following characters
61+
ASSERT_TRUE(dst[3] == L'4');
62+
ASSERT_TRUE(dst[4] == L'\0');
63+
// Should still return length of src
64+
ASSERT_EQ(res, size_t(2));
65+
}

utils/bazel/llvm-project-overlay/libc/BUILD.bazel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5829,6 +5829,19 @@ libc_function(
58295829
],
58305830
)
58315831

5832+
libc_function(
5833+
name = "wcslcpy",
5834+
srcs = ["src/wchar/wcslcpy.cpp"],
5835+
hdrs = ["src/wchar/wcslcpy.h"],
5836+
deps = [
5837+
":__support_common",
5838+
":__support_macros_config",
5839+
":string_utils",
5840+
":types_size_t",
5841+
":types_wchar_t",
5842+
],
5843+
)
5844+
58325845
libc_function(
58335846
name = "wcslen",
58345847
srcs = ["src/wchar/wcslen.cpp"],

utils/bazel/llvm-project-overlay/libc/test/src/wchar/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ libc_test(
8383
],
8484
)
8585

86+
libc_test(
87+
name = "wcslcpy_test",
88+
srcs = ["wcslcpy_test.cpp"],
89+
deps = [
90+
"//libc:types_size_t",
91+
"//libc:types_wchar_t",
92+
"//libc:wcslcpy",
93+
],
94+
)
95+
8696
libc_test(
8797
name = "wcslen_test",
8898
srcs = ["wcslen_test.cpp"],

0 commit comments

Comments
 (0)