From 43af65b21e693ff03981a481549ac81b534982cc Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 30 Mar 2023 19:57:12 +0300 Subject: [PATCH] Implement strcasecmp, wcslen and wcsrtombs --- Library/Convert.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++ include/convert.h | 11 +++++- include/types.h | 6 ++- 3 files changed, 105 insertions(+), 3 deletions(-) diff --git a/Library/Convert.cpp b/Library/Convert.cpp index fa6c4145..bfbc98a3 100644 --- a/Library/Convert.cpp +++ b/Library/Convert.cpp @@ -424,6 +424,97 @@ EXTERNC char *strtok(char *src, const char *delim) return NULL; } +int strcasecmp(const char *s1, const char *s2) +{ + const unsigned char *p1 = (const unsigned char *)s1; + const unsigned char *p2 = (const unsigned char *)s2; + int result; + if (p1 == p2) + return 0; + while ((result = std::tolower(*p1) - std::tolower(*p2++)) == 0) + if (*p1++ == '\0') + break; + return result; +} + +size_t wcslen(const wchar_t *s) +{ + size_t len = 0; + + while (s[len] != L'\0') + { + if (s[++len] == L'\0') + return len; + if (s[++len] == L'\0') + return len; + if (s[++len] == L'\0') + return len; + ++len; + } + + return len; +} + +size_t wcsrtombs(char *dst, const wchar_t **src, size_t len, mbstate_t *ps) +{ + size_t count = 0; + + while (len > 0) + { + wchar_t wc = **src; + if (wc == L'\0') + break; + + if (wc < 0x80) + { + if (dst) + *dst++ = (char)wc; + count++; + len--; + } + else if (wc < 0x800) + { + if (dst) + { + *dst++ = (char)(0xC0 | (wc >> 6)); + *dst++ = (char)(0x80 | (wc & 0x3F)); + } + count += 2; + len -= 2; + } + else if (wc < 0x10000) + { + if (dst) + { + *dst++ = (char)(0xE0 | (wc >> 12)); + *dst++ = (char)(0x80 | ((wc >> 6) & 0x3F)); + *dst++ = (char)(0x80 | (wc & 0x3F)); + } + count += 3; + len -= 3; + } + else + { + if (dst) + { + *dst++ = (char)(0xF0 | (wc >> 18)); + *dst++ = (char)(0x80 | ((wc >> 12) & 0x3F)); + *dst++ = (char)(0x80 | ((wc >> 6) & 0x3F)); + *dst++ = (char)(0x80 | (wc & 0x3F)); + } + count += 4; + len -= 4; + } + + (*src)++; + } + + if (dst) + *dst = '\0'; + + return count; +} + EXTERNC int atoi(const char *String) { uint64_t Length = strlen((char *)String); diff --git a/include/convert.h b/include/convert.h index d9c72366..7515f6db 100644 --- a/include/convert.h +++ b/include/convert.h @@ -5,6 +5,13 @@ extern "C" { #endif + + typedef struct mbstate_t + { + int count; + unsigned int value; + } mbstate_t; + #define NAN (__builtin_nanf("")) int isdigit(int c); @@ -71,9 +78,11 @@ extern "C" char *strchr(const char *String, int Char); char *strrchr(const char *String, int Char); int strncasecmp(const char *lhs, const char *rhs, long unsigned int Count); - int strcasecmp(const char *lhs, const char *rhs); + int strcasecmp(const char *s1, const char *s2); char *strtok(char *src, const char *delim); long int strtol(const char *str, char **endptr, int base); + size_t wcslen(const wchar_t *s); + size_t wcsrtombs(char *dst, const wchar_t **src, size_t len, mbstate_t *ps); int log2(unsigned int n); void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen); diff --git a/include/types.h b/include/types.h index 20fa1ec1..f91952a6 100644 --- a/include/types.h +++ b/include/types.h @@ -152,7 +152,9 @@ typedef __UINTMAX_TYPE__ uintmax_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __SIZE_TYPE__ size_t; -// typedef __WCHAR_TYPE__ wchar_t; +#ifndef __cplusplus +typedef __WCHAR_TYPE__ wchar_t; +#endif typedef __WINT_TYPE__ wint_t; typedef __SIG_ATOMIC_TYPE__ sig_atomic_t; // TODO: ssize_t @@ -243,7 +245,7 @@ typedef int48_t int_least48_t; typedef uint48_t uint_least48_t; typedef int48_t int_fast48_t; typedef uint48_t uint_fast48_t; -#else // __INT48_TYPE__ +#else // __INT48_TYPE__ typedef __INT64_TYPE__ int48_t; typedef __UINT64_TYPE__ uint48_t; typedef int48_t int_least48_t;