Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wchar.btowc
libc.src.wchar.wcslen
libc.src.wchar.wctob
libc.src.wchar.wmemset
libc.src.wchar.wcschr

# sys/uio.h entrypoints
Expand Down
8 changes: 8 additions & 0 deletions libc/include/wchar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ functions:
return_type: wint_t
arguments:
- type: int
- name: wmemset
standards:
- stdc
return_type: wchar_t*
arguments:
- type: wchar_t*
- type: wchar_t
- type: size_t
- name: wcschr
standards:
- stdc
Expand Down
12 changes: 12 additions & 0 deletions libc/src/wchar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ add_entrypoint_object(
libc.src.__support.wctype_utils
)

add_entrypoint_object(
wmemset
SRCS
wmemset.cpp
HDRS
wmemset.h
DEPENDS
libc.hdr.types.size_t
libc.hdr.types.wchar_t
libc.src.__support.wctype_utils
)

add_entrypoint_object(
wcschr
SRCS
Expand Down
24 changes: 24 additions & 0 deletions libc/src/wchar/wmemset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-- Implementation of wmemset -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/wchar/wmemset.h"

#include "hdr/types/size_t.h"
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(wchar_t *, wmemset, (wchar_t * s, wchar_t c, size_t n)) {
for (size_t i = 0; i < n; i++)
s[i] = c;

return s;
}

} // namespace LIBC_NAMESPACE_DECL
23 changes: 23 additions & 0 deletions libc/src/wchar/wmemset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- Implementation header for wmemset
//----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_WCHAR_WMEMSET_H
#define LLVM_LIBC_SRC_WCHAR_WMEMSET_H

#include "hdr/types/size_t.h"
#include "hdr/types/wchar_t.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_WCHAR_WMEMSET_H
12 changes: 12 additions & 0 deletions libc/test/src/wchar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ add_libc_test(
libc.src.wchar.wctob
)

add_libc_test(
wmemset_test
SUITE
libc_wchar_unittests
SRCS
wmemset_test.cpp
DEPENDS
libc.hdr.types.size_t
libc.hdr.types.wchar_t
libc.src.wchar.wmemset
)

add_libc_test(
wcschr_test
SUITE
Expand Down
88 changes: 88 additions & 0 deletions libc/test/src/wchar/wmemset_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//===-- Unittests for wmemset ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "hdr/types/size_t.h"
#include "hdr/types/wchar_t.h"
#include "src/wchar/wmemset.h"
#include "test/UnitTest/Test.h"

TEST(LlvmLibcWMemsetTest, SmallStringBoundCheck) {
wchar_t str[5];
for (int i = 0; i < 5; i++)
str[i] = 'A';

wchar_t *output = LIBC_NAMESPACE::wmemset(str + 1, 'B', 3);

EXPECT_EQ(output, str + 1);

// EXPECT_TRUE being used since there isn't currently support for printing
// wide chars in the future, it would be preferred to switch these to
// EXPECT_EQ
EXPECT_TRUE(str[0] == (wchar_t)'A');
EXPECT_TRUE(str[1] == (wchar_t)'B');
EXPECT_TRUE(str[2] == (wchar_t)'B');
EXPECT_TRUE(str[3] == (wchar_t)'B');
EXPECT_TRUE(str[4] == (wchar_t)'A');
}

TEST(LlvmLibcWMemsetTest, LargeStringBoundCheck) {
constexpr int str_size = 1000;
wchar_t str[str_size];
for (int i = 0; i < str_size; i++)
str[i] = 'A';

wchar_t *output = LIBC_NAMESPACE::wmemset(str + 1, 'B', str_size - 2);

EXPECT_EQ(output, str + 1);

EXPECT_TRUE(str[0] == (wchar_t)'A');
for (int i = 1; i < str_size - 1; i++)
EXPECT_TRUE(str[i] == (wchar_t)'B');

EXPECT_TRUE(str[str_size - 1] == (wchar_t)'A');
}

TEST(LlvmLibcWMemsetTest, WCharSizeSmallString) {
// ensure we can handle full range of widechars
wchar_t str[5];
const wchar_t target = WCHAR_MAX;

for (int i = 0; i < 5; i++)
str[i] = 'A';

wchar_t *output = LIBC_NAMESPACE::wmemset(str + 1, target, 3);

EXPECT_EQ(output, str + 1);

EXPECT_TRUE(str[0] == (wchar_t)'A');
EXPECT_TRUE(str[1] == target);
EXPECT_TRUE(str[2] == target);
EXPECT_TRUE(str[3] == target);
EXPECT_TRUE(str[4] == (wchar_t)'A');
}

TEST(LlvmLibcWMemsetTest, WCharSizeLargeString) {
// ensure we can handle full range of widechars
constexpr int str_size = 1000;
wchar_t str[str_size];

const wchar_t target = WCHAR_MAX;

for (int i = 0; i < str_size; i++)
str[i] = 'A';

wchar_t *output = LIBC_NAMESPACE::wmemset(str + 1, target, str_size - 2);

EXPECT_EQ(output, str + 1);

EXPECT_TRUE(str[0] == (wchar_t)'A');
for (int i = 1; i < str_size - 1; i++)
EXPECT_TRUE(str[i] == target);

EXPECT_TRUE(str[str_size - 1] == (wchar_t)'A');
}
Loading