summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Tests/LibC/TestWchar.cpp35
-rw-r--r--Userland/Libraries/LibC/wchar.cpp10
2 files changed, 42 insertions, 3 deletions
diff --git a/Tests/LibC/TestWchar.cpp b/Tests/LibC/TestWchar.cpp
index dc173eccb4..2e42de4057 100644
--- a/Tests/LibC/TestWchar.cpp
+++ b/Tests/LibC/TestWchar.cpp
@@ -439,3 +439,38 @@ TEST_CASE(wcslcpy)
ret = wcslcpy(nullptr, L"abc", 0);
EXPECT_EQ(ret, 3ul);
}
+
+TEST_CASE(mbrlen)
+{
+ size_t ret = 0;
+ mbstate_t state = {};
+
+ // Ensure that we can parse normal ASCII characters.
+ ret = mbrlen("Hello", 5, &state);
+ EXPECT_EQ(ret, 1ul);
+
+ // Try two three-byte codepoints (™™), only one of which should be consumed.
+ ret = mbrlen("\xe2\x84\xa2\xe2\x84\xa2", 6, &state);
+ EXPECT_EQ(ret, 3ul);
+
+ // Try a null character, which should return 0 and reset the state to the initial state.
+ ret = mbrlen("\x00\x00", 2, &state);
+ EXPECT_EQ(ret, 0ul);
+ EXPECT_NE(mbsinit(&state), 0);
+
+ // Try an incomplete multibyte character.
+ ret = mbrlen("\xe2\x84", 2, &state);
+ EXPECT_EQ(ret, -2ul);
+ EXPECT_EQ(mbsinit(&state), 0);
+
+ // Finish the previous multibyte character.
+ ret = mbrlen("\xa2", 1, &state);
+ EXPECT_EQ(ret, 1ul);
+
+ // Try an invalid multibyte sequence.
+ // Reset the state afterwards because the effects are undefined.
+ ret = mbrlen("\xff", 1, &state);
+ EXPECT_EQ(ret, -1ul);
+ EXPECT_EQ(errno, EILSEQ);
+ state = {};
+}
diff --git a/Userland/Libraries/LibC/wchar.cpp b/Userland/Libraries/LibC/wchar.cpp
index b408e4fb71..d42c15cbf0 100644
--- a/Userland/Libraries/LibC/wchar.cpp
+++ b/Userland/Libraries/LibC/wchar.cpp
@@ -300,10 +300,14 @@ size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* state)
return consumed_bytes;
}
-size_t mbrlen(const char*, size_t, mbstate_t*)
+size_t mbrlen(const char* s, size_t n, mbstate_t* ps)
{
- dbgln("FIXME: Implement mbrlen()");
- TODO();
+ static mbstate_t anonymous_state = {};
+
+ if (ps == nullptr)
+ ps = &anonymous_state;
+
+ return mbrtowc(nullptr, s, n, ps);
}
size_t wcrtomb(char* s, wchar_t wc, mbstate_t*)