Skip to content

Commit 631a6e0

Browse files
[libc][wchar] implement wcslen (#124150)
Update string_utils' string_length to work with char* or wchar_t*, so that it may be reusable when implementing wmemchr, wcspbrk, wcsrchr, wcsstr. Link: #121183 Link: #124027 Co-authored-by: Nick Desaulniers <[email protected]> --------- Co-authored-by: Tristan Ross <[email protected]>
1 parent 3ed28bb commit 631a6e0

File tree

13 files changed

+112
-13
lines changed

13 files changed

+112
-13
lines changed

libc/config/gpu/amdgpu/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ set(TARGET_LIBC_ENTRYPOINTS
261261
libc.src.time.nanosleep
262262

263263
# wchar.h entrypoints
264+
libc.src.wchar.wcslen
264265
libc.src.wchar.wctob
265266

266267
# locale.h entrypoints

libc/config/gpu/nvptx/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ set(TARGET_LIBC_ENTRYPOINTS
261261
libc.src.time.nanosleep
262262

263263
# wchar.h entrypoints
264+
libc.src.wchar.wcslen
264265
libc.src.wchar.wctob
265266

266267
# locale.h entrypoints

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ set(TARGET_LIBC_ENTRYPOINTS
350350
libc.src.unistd.write
351351

352352
# wchar.h entrypoints
353+
libc.src.wchar.wcslen
353354
libc.src.wchar.wctob
354355

355356
# sys/uio.h entrypoints

libc/config/linux/riscv/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ set(TARGET_LIBC_ENTRYPOINTS
346346
libc.src.unistd.write
347347

348348
# wchar.h entrypoints
349+
libc.src.wchar.wcslen
349350
libc.src.wchar.wctob
350351
)
351352

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,9 @@ set(TARGET_LIBC_ENTRYPOINTS
349349
libc.src.unistd.write
350350

351351
# wchar.h entrypoints
352-
libc.src.wchar.wctob
353352
libc.src.wchar.btowc
353+
libc.src.wchar.wcslen
354+
libc.src.wchar.wctob
354355

355356
# sys/uio.h entrypoints
356357
libc.src.sys.uio.writev

libc/include/wchar.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ types:
99
enums: []
1010
objects: []
1111
functions:
12+
- name: wcslen
13+
standards:
14+
- stdc
15+
return_type: size_t
16+
arguments:
17+
- type: const wchar_t *
1218
- name: wctob
1319
standards:
1420
- stdc

libc/src/string/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ add_header_library(
1717
DEPENDS
1818
.memory_utils.inline_bzero
1919
.memory_utils.inline_memcpy
20+
libc.hdr.types.size_t
2021
libc.include.stdlib
21-
libc.src.__support.common
2222
libc.src.__support.CPP.bitset
23+
libc.src.__support.CPP.type_traits
24+
libc.src.__support.common
2325
${string_config_options}
2426
)
2527

libc/src/string/string_utils.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
#ifndef LLVM_LIBC_SRC_STRING_STRING_UTILS_H
1515
#define LLVM_LIBC_SRC_STRING_STRING_UTILS_H
1616

17+
#include "hdr/types/size_t.h"
1718
#include "src/__support/CPP/bitset.h"
19+
#include "src/__support/CPP/type_traits.h" // cpp::is_same_v
1820
#include "src/__support/macros/config.h"
1921
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
2022
#include "src/string/memory_utils/inline_bzero.h"
2123
#include "src/string/memory_utils/inline_memcpy.h"
22-
#include <stddef.h> // For size_t
2324

2425
namespace LIBC_NAMESPACE_DECL {
2526
namespace internal {
@@ -79,24 +80,21 @@ LIBC_INLINE size_t string_length_wide_read(const char *src) {
7980
return char_ptr - src;
8081
}
8182

82-
LIBC_INLINE size_t string_length_byte_read(const char *src) {
83-
size_t length;
84-
for (length = 0; *src; ++src, ++length)
85-
;
86-
return length;
87-
}
88-
8983
// Returns the length of a string, denoted by the first occurrence
9084
// of a null terminator.
91-
LIBC_INLINE size_t string_length(const char *src) {
85+
template <typename T> LIBC_INLINE size_t string_length(const T *src) {
9286
#ifdef LIBC_COPT_STRING_UNSAFE_WIDE_READ
9387
// Unsigned int is the default size for most processors, and on x86-64 it
9488
// performs better than larger sizes when the src pointer can't be assumed to
9589
// be aligned to a word boundary, so it's the size we use for reading the
9690
// string a block at a time.
97-
return string_length_wide_read<unsigned int>(src);
91+
if constexpr (cpp::is_same_v<T, char>)
92+
return string_length_wide_read<unsigned int>(src);
9893
#else
99-
return string_length_byte_read(src);
94+
size_t length;
95+
for (length = 0; *src; ++src, ++length)
96+
;
97+
return length;
10098
#endif
10199
}
102100

libc/src/wchar/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
add_entrypoint_object(
2+
wcslen
3+
SRCS
4+
wcslen.cpp
5+
HDRS
6+
wcslen.h
7+
DEPENDS
8+
libc.hdr.types.size_t
9+
libc.hdr.types.wchar_t
10+
libc.src.string.string_utils
11+
)
112

213
add_entrypoint_object(
314
wctob

libc/src/wchar/wcslen.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation of wcslen ------------------------------------------===//
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/wcslen.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" // string_length_trivial
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
LLVM_LIBC_FUNCTION(size_t, wcslen, (const wchar_t *src)) {
20+
return internal::string_length(src);
21+
}
22+
23+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcslen.h

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

libc/test/src/wchar/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
add_custom_target(libc_wchar_unittests)
22

3+
add_libc_test(
4+
wcslen_test
5+
SUITE
6+
libc_wchar_unittests
7+
SRCS
8+
wcslen_test.cpp
9+
DEPENDS
10+
libc.hdr.types.size_t
11+
libc.hdr.types.wchar_t
12+
libc.src.wchar.wcslen
13+
)
14+
315
add_libc_test(
416
btowc_test
517
SUITE

libc/test/src/wchar/wcslen_test.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Unittests for wcslen ----------------------------------------------===//
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/wcslen.h"
12+
#include "test/UnitTest/Test.h"
13+
14+
TEST(LlvmLibcWCSLenTest, EmptyString) {
15+
ASSERT_EQ(size_t{0}, LIBC_NAMESPACE::wcslen(L""));
16+
}
17+
18+
TEST(LlvmLibcWCSLenTest, AnyString) {
19+
ASSERT_EQ(size_t{12}, LIBC_NAMESPACE::wcslen(L"Hello World!"));
20+
}

0 commit comments

Comments
 (0)