From 996c5ebe74d736fffe1f43b4ad9c03185b51a998 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 22 Apr 2025 00:41:59 +0300 Subject: [PATCH] LibC: Implement `strxfrm_l` --- userspace/libraries/LibC/string.cpp | 54 ++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/userspace/libraries/LibC/string.cpp b/userspace/libraries/LibC/string.cpp index b15b711a..e1a4dce9 100644 --- a/userspace/libraries/LibC/string.cpp +++ b/userspace/libraries/LibC/string.cpp @@ -156,7 +156,12 @@ char* strncat(char* __restrict__ dest, const char* __restrict__ src, size_t n) int strcoll(const char* s1, const char* s2) { - switch (__getlocale(LC_COLLATE)) + return strcoll_l(s1, s2, __getlocale(LC_COLLATE)); +} + +int strcoll_l(const char *s1, const char *s2, locale_t locale) +{ + switch (locale) { case LOCALE_INVALID: ASSERT_NOT_REACHED(); @@ -362,6 +367,53 @@ char* strtok_r(char* __restrict str, const char* __restrict sep, char** __restri return str; } +size_t strxfrm(char* __restrict s1, const char* __restrict s2, size_t n) +{ + return strxfrm_l(s1, s2, n, __getlocale(LC_COLLATE)); +} + +size_t strxfrm_l(char* __restrict s1, const char* __restrict s2, size_t n, locale_t locale) +{ + (void)s1; + (void)s2; + (void)n; + ASSERT_NOT_REACHED(); + + + switch (locale) + { + case LOCALE_INVALID: + ASSERT_NOT_REACHED(); + case LOCALE_POSIX: + return strcmp(s1, s2); + case LOCALE_UTF8: + { + const unsigned char* u1 = (unsigned char*)s1; + const unsigned char* u2 = (unsigned char*)s2; + if (!*u1 || !*u2) + return *u1 - *u2; + + wchar_t wc1, wc2; + while (*u1 && *u2) + { + wc1 = BAN::UTF8::to_codepoint(u1); + wc2 = BAN::UTF8::to_codepoint(u2); + if (wc1 == (wchar_t)BAN::UTF8::invalid || wc2 == (wchar_t)BAN::UTF8::invalid) + { + errno = EINVAL; + return -1; + } + if (wc1 != wc2) + break; + u1 += BAN::UTF8::byte_length(*u1); + u2 += BAN::UTF8::byte_length(*u2); + } + return wc1 - wc2; + } + } + ASSERT_NOT_REACHED(); +} + char* strsignal(int signum) { static char buffer[128];