Skip to content

Commit d721d4e

Browse files
authored
[libc] Implemented wcspbrk (#142040)
Implemented wcspbrk and added tests
1 parent 0e90a84 commit d721d4e

File tree

7 files changed

+146
-0
lines changed

7 files changed

+146
-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
libc.src.wchar.wctob
367367
libc.src.wchar.wmemset
368368
libc.src.wchar.wcschr
369+
libc.src.wchar.wcspbrk
369370
libc.src.wchar.wcsspn
370371
libc.src.wchar.wmemcmp
371372

libc/include/wchar.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ functions:
4242
arguments:
4343
- type: const wchar_t *
4444
- type: wchar_t
45+
- name: wcspbrk
46+
standards:
47+
- stdc
48+
return_type: const wchar_t *
49+
arguments:
50+
- type: const wchar_t *
51+
- type: const wchar_t *
4552
- name: wcsspn
4653
standards:
4754
- stdc

libc/src/wchar/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ add_entrypoint_object(
5757
libc.src.__support.wctype_utils
5858
)
5959

60+
add_entrypoint_object(
61+
wcspbrk
62+
SRCS
63+
wcspbrk.cpp
64+
HDRS
65+
wcspbrk.h
66+
DEPENDS
67+
libc.hdr.wchar_macros
68+
libc.src.__support.wctype_utils
69+
)
70+
6071
add_entrypoint_object(
6172
wcsspn
6273
SRCS

libc/src/wchar/wcspbrk.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===-- Implementation of wcspbrk -----------------------------------------===//
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/wcspbrk.h"
10+
11+
#include "hdr/types/wchar_t.h"
12+
#include "src/__support/common.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
16+
bool contains_char(const wchar_t *str, wchar_t target) {
17+
for (; *str != L'\0'; str++)
18+
if (*str == target)
19+
return true;
20+
21+
return false;
22+
}
23+
24+
LLVM_LIBC_FUNCTION(const wchar_t *, wcspbrk,
25+
(const wchar_t *src, const wchar_t *breakset)) {
26+
// currently O(n * m), can be further optimized to O(n + m) with a hash set
27+
for (int src_idx = 0; src[src_idx] != 0; src_idx++)
28+
if (contains_char(breakset, src[src_idx]))
29+
return src + src_idx;
30+
31+
return nullptr;
32+
}
33+
34+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcspbrk.h

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

libc/test/src/wchar/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ add_libc_test(
5555
libc.src.wchar.wcschr
5656
)
5757

58+
add_libc_test(
59+
wcspbrk_test
60+
SUITE
61+
libc_wchar_unittests
62+
SRCS
63+
wcspbrk_test.cpp
64+
DEPENDS
65+
libc.src.wchar.wcspbrk
66+
)
67+
5868
add_libc_test(
5969
wcsspn_test
6070
SUITE

libc/test/src/wchar/wcspbrk_test.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===-- Unittests for wcspbrk ---------------------------------------------===//
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/wcspbrk.h"
11+
#include "test/UnitTest/Test.h"
12+
13+
TEST(LlvmLibcWCSPBrkTest, EmptyStringShouldReturnNullptr) {
14+
// The search should not include the null terminator.
15+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(L"", L""), nullptr);
16+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(L"_", L""), nullptr);
17+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(L"", L"_"), nullptr);
18+
}
19+
20+
TEST(LlvmLibcWCSPBrkTest, ShouldNotFindAnythingAfterNullTerminator) {
21+
const wchar_t src[4] = {'a', 'b', '\0', 'c'};
22+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"c"), nullptr);
23+
}
24+
25+
TEST(LlvmLibcWCSPBrkTest, ShouldReturnNullptrIfNoCharactersFound) {
26+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(L"12345", L"abcdef"), nullptr);
27+
}
28+
29+
TEST(LlvmLibcWCSPBrkTest, FindsFirstCharacter) {
30+
const wchar_t *src = L"12345";
31+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"1"), src);
32+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"-1"), src);
33+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"1_"), src);
34+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"f1_"), src);
35+
}
36+
37+
TEST(LlvmLibcWCSPBrkTest, FindsMiddleCharacter) {
38+
const wchar_t *src = L"12345";
39+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"3"), src + 2);
40+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"?3"), src + 2);
41+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"3F"), src + 2);
42+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"z3_"), src + 2);
43+
}
44+
45+
TEST(LlvmLibcWCSPBrkTest, FindsLastCharacter) {
46+
const wchar_t *src = L"12345";
47+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"5"), src + 4);
48+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"r5"), src + 4);
49+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"59"), src + 4);
50+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"n5_"), src + 4);
51+
}
52+
53+
TEST(LlvmLibcWCSPBrkTest, FindsFirstOfRepeated) {
54+
const wchar_t *src = L"A,B,C,D";
55+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L","), src + 1);
56+
}
57+
58+
TEST(LlvmLibcWCSPBrkTest, FindsFirstInBreakset) {
59+
const wchar_t *src = L"12345";
60+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"34"), src + 2);
61+
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"43"), src + 2);
62+
}

0 commit comments

Comments
 (0)