Skip to content

Commit ac7e391

Browse files
sribee8Sriya Pratipati
andauthored
[libc] Implemented wcsnlen (#145610)
Implemented wcsnlen and tests for the function. --------- Co-authored-by: Sriya Pratipati <[email protected]>
1 parent af2bf2e commit ac7e391

File tree

7 files changed

+132
-0
lines changed

7 files changed

+132
-0
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ set(TARGET_LIBC_ENTRYPOINTS
366366
# wchar.h entrypoints
367367
libc.src.wchar.btowc
368368
libc.src.wchar.wcslen
369+
libc.src.wchar.wcsnlen
369370
libc.src.wchar.wctob
370371
libc.src.wchar.wmemmove
371372
libc.src.wchar.wmemset

libc/include/wchar.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ functions:
1717
return_type: size_t
1818
arguments:
1919
- type: const wchar_t *
20+
- name: wcsnlen
21+
standards:
22+
- stdc
23+
return_type: size_t
24+
arguments:
25+
- type: const wchar_t *
26+
- type: size_t
2027
- name: wctob
2128
standards:
2229
- stdc

libc/src/wchar/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ add_entrypoint_object(
1010
libc.src.string.string_utils
1111
)
1212

13+
add_entrypoint_object(
14+
wcsnlen
15+
SRCS
16+
wcsnlen.cpp
17+
HDRS
18+
wcsnlen.h
19+
DEPENDS
20+
libc.hdr.types.size_t
21+
libc.hdr.types.wchar_t
22+
)
23+
1324
add_entrypoint_object(
1425
wctob
1526
SRCS

libc/src/wchar/wcsnlen.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- Implementation of wcsnlen -----------------------------------------===//
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/wcsnlen.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+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
LLVM_LIBC_FUNCTION(size_t, wcsnlen, (const wchar_t *src, size_t maxlen)) {
19+
size_t i = 0;
20+
for (; i < maxlen && src[i]; ++i)
21+
;
22+
return i;
23+
}
24+
25+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcsnlen.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===-- Implementation header for wcsnlen ---------------------------------===//
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_WCSNLEN_H
10+
#define LLVM_LIBC_SRC_WCHAR_WCSNLEN_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 wcsnlen(const wchar_t *src, size_t maxlen);
19+
20+
} // namespace LIBC_NAMESPACE_DECL
21+
22+
#endif // LLVM_LIBC_SRC_WCHAR_WCSNLEN_H

libc/test/src/wchar/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@ add_libc_test(
1212
libc.src.wchar.wcslen
1313
)
1414

15+
add_libc_test(
16+
wcsnlen_test
17+
SUITE
18+
libc_wchar_unittests
19+
SRCS
20+
wcsnlen_test.cpp
21+
DEPENDS
22+
libc.hdr.types.size_t
23+
libc.hdr.types.wchar_t
24+
libc.src.wchar.wcsnlen
25+
)
26+
1527
add_libc_test(
1628
btowc_test
1729
SUITE

libc/test/src/wchar/wcsnlen_test.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===-- Unittests for wcsnlen ---------------------------------------------===//
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/wcsnlen.h"
12+
#include "test/UnitTest/Test.h"
13+
14+
TEST(LlvmLibcWCSNLenTest, EmptyString) {
15+
ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::wcsnlen(L"", 0));
16+
// If N is greater than string length, this should still return 0.
17+
ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::wcsnlen(L"", 1));
18+
}
19+
20+
TEST(LlvmLibcWCSNLenTest, OneCharacterString) {
21+
const wchar_t *src = L"A";
22+
ASSERT_EQ(static_cast<size_t>(1), LIBC_NAMESPACE::wcsnlen(src, 1));
23+
// If N is 0, this should return 0.
24+
ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::wcsnlen(src, 0));
25+
// If N is greater than string length, this should still return 1.
26+
ASSERT_EQ(static_cast<size_t>(1), LIBC_NAMESPACE::wcsnlen(src, 3));
27+
}
28+
29+
TEST(LlvmLibcWCSNLenTest, ManyCharacterString) {
30+
const wchar_t *src = L"123456789";
31+
ASSERT_EQ(static_cast<size_t>(9), LIBC_NAMESPACE::wcsnlen(src, 9));
32+
// If N is 0, this should return 0.
33+
ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::wcsnlen(src, 0));
34+
// If N is smaller than the string length, it should return N.
35+
ASSERT_EQ(static_cast<size_t>(3), LIBC_NAMESPACE::wcsnlen(src, 3));
36+
// If N is greater than string length, this should still return 9.
37+
ASSERT_EQ(static_cast<size_t>(9), LIBC_NAMESPACE::wcsnlen(src, 42));
38+
}
39+
40+
TEST(LlvmLibcWCSNLenTest, IgnoreCharactersAfterNullTerminator) {
41+
const wchar_t src[5] = {L'a', L'b', L'c', L'\0', L'd'};
42+
ASSERT_EQ(static_cast<size_t>(3), LIBC_NAMESPACE::wcsnlen(src, 3));
43+
// This should only read up to the null terminator.
44+
ASSERT_EQ(static_cast<size_t>(3), LIBC_NAMESPACE::wcsnlen(src, 4));
45+
ASSERT_EQ(static_cast<size_t>(3), LIBC_NAMESPACE::wcsnlen(src, 5));
46+
}
47+
48+
TEST(LlvmLibcWCSNLenTest, NoNullTerminator) {
49+
const wchar_t src[4] = {L'a', L'b', L'c', L'd'};
50+
// Should return 4
51+
ASSERT_EQ(static_cast<size_t>(4), LIBC_NAMESPACE::wcsnlen(src, 4));
52+
// Should return 2 since N is smaller than string length
53+
ASSERT_EQ(static_cast<size_t>(2), LIBC_NAMESPACE::wcsnlen(src, 2));
54+
}

0 commit comments

Comments
 (0)