Skip to content

Commit 22dd9a2

Browse files
sribee8Sriya Pratipati
andauthored
[libc] wmemchr implementation (#142640)
Implemented wmemchr and tests. Fixes: #121183 --------- Co-authored-by: Sriya Pratipati <[email protected]>
1 parent 2ff2a07 commit 22dd9a2

File tree

7 files changed

+171
-0
lines changed

7 files changed

+171
-0
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ set(TARGET_LIBC_ENTRYPOINTS
379379
libc.src.wchar.wcsstr
380380
libc.src.wchar.wcsncat
381381
libc.src.wchar.wcscpy
382+
libc.src.wchar.wmemchr
382383

383384
# sys/uio.h entrypoints
384385
libc.src.sys.uio.writev

libc/include/wchar.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ functions:
8686
- type: const wchar_t *
8787
- type: const wchar_t *
8888
- type: size_t
89+
- name: wmemchr
90+
standards:
91+
- stdc
92+
return_type: const wchar_t *
93+
arguments:
94+
- type: const wchar_t *
95+
- type: wchar_t
96+
- type: size_t
8997
- name: wmempcpy
9098
standards:
9199
- gnu

libc/src/wchar/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ add_entrypoint_object(
185185
libc.src.string.string_utils
186186
)
187187

188+
add_entrypoint_object(
189+
wmemchr
190+
SRCS
191+
wmemchr.cpp
192+
HDRS
193+
wmemchr.h
194+
DEPENDS
195+
libc.hdr.types.size_t
196+
libc.hdr.wchar_macros
197+
)
198+
188199
add_entrypoint_object(
189200
wmempcpy
190201
SRCS

libc/src/wchar/wmemchr.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===-- Implementation of wmemchr -----------------------------------------===//
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/wmemchr.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(const wchar_t *, wmemchr,
19+
(const wchar_t *s, wchar_t c, size_t n)) {
20+
size_t i = 0;
21+
for (; i < n; ++i)
22+
if (s[i] == c)
23+
return (s + i);
24+
return nullptr;
25+
}
26+
27+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wmemchr.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===-- Implementation header for wmemchr ---------------------------------===//
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_WMEMCHR_H
10+
#define LLVM_LIBC_SRC_WCHAR_WMEMCHR_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+
const wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n);
19+
20+
} // namespace LIBC_NAMESPACE_DECL
21+
22+
#endif // LLVM_LIBC_SRC_WCHAR_WMEMCHR_H

libc/test/src/wchar/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ add_libc_test(
105105
libc.src.wchar.wcsspn
106106
)
107107

108+
add_libc_test(
109+
wmemchr_test
110+
SUITE
111+
libc_wchar_unittests
112+
SRCS
113+
wmemchr_test.cpp
114+
DEPENDS
115+
libc.src.wchar.wmemchr
116+
)
117+
108118
add_libc_test(
109119
wmemcmp_test
110120
SUITE

libc/test/src/wchar/wmemchr_test.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//===-- Unittests for wmemchr ---------------------------------------------===//
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/wchar_t.h"
10+
#include "src/wchar/wmemchr.h"
11+
#include "test/UnitTest/Test.h"
12+
13+
TEST(LlvmLibcWMemChrTest, FindsCharacterAfterNullTerminator) {
14+
// wmemchr should continue searching after a null terminator.
15+
const size_t size = 5;
16+
const wchar_t src[size] = {L'a', L'\0', L'b', L'c', L'\0'};
17+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'b', size), (src + 2));
18+
}
19+
20+
TEST(LlvmLibcWMemChrTest, FindsCharacterInNonNullTerminatedCollection) {
21+
const size_t size = 3;
22+
const wchar_t src[size] = {L'a', L'b', L'c'};
23+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'b', size), (src + 1));
24+
}
25+
26+
TEST(LlvmLibcWMemChrTest, FindsFirstCharacter) {
27+
const size_t size = 6;
28+
const wchar_t *src = L"abcde";
29+
// Should return original array since 'a' is the first character.
30+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'a', size), (src));
31+
}
32+
33+
TEST(LlvmLibcWMemChrTest, FindsMiddleCharacter) {
34+
const size_t size = 6;
35+
const wchar_t *src = L"abcde";
36+
// Should return characters after and including 'c'.
37+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'c', size), (src + 2));
38+
}
39+
40+
TEST(LlvmLibcWMemChrTest, FindsLastCharacterThatIsNotNullTerminator) {
41+
const size_t size = 6;
42+
const wchar_t *src = L"abcde";
43+
// Should return 'e' and null terminator.
44+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'e', size), (src + 4));
45+
}
46+
47+
TEST(LlvmLibcWMemChrTest, FindsNullTerminator) {
48+
const size_t size = 6;
49+
const wchar_t *src = L"abcde";
50+
// Should return null terminator.
51+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'\0', size), (src + 5));
52+
}
53+
54+
TEST(LlvmLibcWMemChrTest, CharacterNotWithinStringShouldReturnNullptr) {
55+
const size_t size = 6;
56+
const wchar_t *src = L"abcde";
57+
// Should return nullptr.
58+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'z', size), nullptr);
59+
}
60+
61+
TEST(LlvmLibcWMemChrTest, CharacterNotWithinSizeShouldReturnNullptr) {
62+
const size_t size = 3;
63+
const wchar_t *src = L"abcde";
64+
// Should return nullptr.
65+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'd', size), nullptr);
66+
}
67+
68+
TEST(LlvmLibcWMemChrTest, TheSourceShouldNotChange) {
69+
const size_t size = 3;
70+
const wchar_t *src = L"ab";
71+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'a', size), src);
72+
ASSERT_TRUE(src[0] == L'a');
73+
ASSERT_TRUE(src[1] == L'b');
74+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'c', size), nullptr);
75+
ASSERT_TRUE(src[0] == L'a');
76+
ASSERT_TRUE(src[1] == L'b');
77+
}
78+
79+
TEST(LlvmLibcWMemChrTest, EmptyStringShouldOnlyMatchNullTerminator) {
80+
const size_t size = 1;
81+
const wchar_t *src = L"";
82+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'\0', size), src);
83+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'c', size), nullptr);
84+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'1', size), nullptr);
85+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'?', size), nullptr);
86+
}
87+
88+
TEST(LlvmLibcWMemChrTest, SingleRepeatedCharacterShouldReturnFirst) {
89+
const size_t size = 6;
90+
const wchar_t *src = L"XXXXX";
91+
ASSERT_EQ(LIBC_NAMESPACE::wmemchr(src, L'X', size), src);
92+
}

0 commit comments

Comments
 (0)