2022-12-16 19:37:57 +00:00
|
|
|
#include <luna/Alloc.h>
|
2022-12-16 19:40:04 +00:00
|
|
|
#include <luna/CString.h>
|
2023-07-22 09:58:28 +00:00
|
|
|
#include <luna/CType.h>
|
2022-11-19 14:43:09 +00:00
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
2022-11-20 17:29:23 +00:00
|
|
|
void* memcpy(void* dest, const void* src, usize n)
|
2022-11-19 14:43:09 +00:00
|
|
|
{
|
2022-11-20 17:29:23 +00:00
|
|
|
for (usize i = 0; i < n; ++i) { *((u8*)dest + i) = *((const u8*)src + i); }
|
2022-11-19 14:43:09 +00:00
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2022-11-20 17:29:23 +00:00
|
|
|
void* memset(void* buf, int c, usize n)
|
2022-11-19 14:43:09 +00:00
|
|
|
{
|
2022-11-20 17:29:23 +00:00
|
|
|
for (usize i = 0; i < n; ++i) { *((u8*)buf + i) = (u8)c; }
|
2022-11-19 14:43:09 +00:00
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2023-07-10 13:30:05 +00:00
|
|
|
void* memchr(const void* buf, int c, usize n)
|
|
|
|
{
|
|
|
|
for (usize i = 0; i < n; ++i)
|
|
|
|
{
|
|
|
|
if (*((const u8*)buf + i) == (u8)c) return const_cast<void*>(buf);
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-11-20 17:29:23 +00:00
|
|
|
int memcmp(const void* a, const void* b, usize n)
|
2022-11-19 14:43:09 +00:00
|
|
|
{
|
|
|
|
if (!n) return 0;
|
|
|
|
const u8* ap = (const u8*)a;
|
|
|
|
const u8* bp = (const u8*)b;
|
|
|
|
while (--n && *ap == *bp)
|
|
|
|
{
|
|
|
|
ap++;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
return *ap - *bp;
|
|
|
|
}
|
|
|
|
|
2022-11-20 17:29:23 +00:00
|
|
|
void* memmove(void* dest, const void* src, usize n)
|
2022-11-19 14:43:09 +00:00
|
|
|
{
|
|
|
|
if (dest == src) return dest;
|
|
|
|
if (dest > src)
|
2022-12-07 10:47:46 +00:00
|
|
|
for (long i = (long)n - 1; i >= 0; i++) { *((u8*)dest + i) = *((const u8*)src + i); }
|
2022-11-19 14:43:09 +00:00
|
|
|
else
|
|
|
|
for (long i = 0; i < (long)n; i++) { *((u8*)dest + i) = *((const u8*)src + i); }
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2022-11-20 17:29:23 +00:00
|
|
|
usize strlen(const char* str)
|
2022-11-19 14:43:09 +00:00
|
|
|
{
|
|
|
|
const char* i = str;
|
|
|
|
for (; *i; ++i)
|
|
|
|
;
|
2022-12-07 10:47:46 +00:00
|
|
|
return (usize)(i - str);
|
2022-11-19 14:43:09 +00:00
|
|
|
}
|
2022-12-16 19:37:57 +00:00
|
|
|
|
2023-01-22 10:27:37 +00:00
|
|
|
usize strnlen(const char* str, usize max)
|
|
|
|
{
|
|
|
|
const char* i = str;
|
2023-01-22 10:43:10 +00:00
|
|
|
for (; *i && max; ++i, --max)
|
2023-01-22 10:27:37 +00:00
|
|
|
;
|
|
|
|
return (usize)(i - str);
|
|
|
|
}
|
|
|
|
|
2022-12-19 11:20:56 +00:00
|
|
|
int strcmp(const char* a, const char* b)
|
|
|
|
{
|
|
|
|
while (*a && (*a == *b))
|
|
|
|
{
|
|
|
|
a++;
|
|
|
|
b++;
|
|
|
|
}
|
|
|
|
return *(const u8*)a - *(const u8*)b;
|
|
|
|
}
|
|
|
|
|
2023-04-28 18:00:26 +00:00
|
|
|
int wcscmp(const wchar_t* a, const wchar_t* b)
|
|
|
|
{
|
|
|
|
while (*a && (*a == *b))
|
|
|
|
{
|
|
|
|
a++;
|
|
|
|
b++;
|
|
|
|
}
|
2023-07-25 15:23:27 +00:00
|
|
|
static_assert(sizeof(wchar_t) == sizeof(u32));
|
|
|
|
return *(const u32*)a - *(const u32*)b;
|
2023-04-28 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
2023-03-12 14:20:44 +00:00
|
|
|
int strncmp(const char* a, const char* b, usize max)
|
|
|
|
{
|
|
|
|
const char* s = a;
|
2023-04-23 08:53:48 +00:00
|
|
|
while (*a && (*a == *b) && (usize)(a - s) < (max - 1))
|
2023-03-12 14:20:44 +00:00
|
|
|
{
|
|
|
|
a++;
|
|
|
|
b++;
|
|
|
|
}
|
|
|
|
return *(const u8*)a - *(const u8*)b;
|
|
|
|
}
|
|
|
|
|
2022-12-18 13:33:13 +00:00
|
|
|
usize wcslen(const wchar_t* str)
|
|
|
|
{
|
|
|
|
const wchar_t* i = str;
|
|
|
|
for (; *i; ++i)
|
|
|
|
;
|
|
|
|
return (usize)(i - str);
|
|
|
|
}
|
|
|
|
|
2022-12-16 19:37:57 +00:00
|
|
|
char* strdup(const char* str)
|
|
|
|
{
|
|
|
|
const usize len = strlen(str);
|
|
|
|
|
2023-04-27 15:36:25 +00:00
|
|
|
char* dest = (char*)calloc_impl(len + 1, 1, false).value_or(nullptr);
|
2023-01-22 10:27:37 +00:00
|
|
|
if (!dest) return nullptr;
|
|
|
|
|
|
|
|
memcpy(dest, str, len);
|
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* strndup(const char* str, usize max)
|
|
|
|
{
|
|
|
|
const usize len = strnlen(str, max);
|
|
|
|
|
2023-04-27 15:36:25 +00:00
|
|
|
char* dest = (char*)calloc_impl(len + 1, 1, false).value_or(nullptr);
|
2022-12-16 19:37:57 +00:00
|
|
|
if (!dest) return nullptr;
|
|
|
|
|
2023-01-22 10:27:37 +00:00
|
|
|
memcpy(dest, str, len);
|
2022-12-16 19:37:57 +00:00
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
2022-12-18 15:31:02 +00:00
|
|
|
|
2023-01-06 15:20:35 +00:00
|
|
|
char* strcpy(char* dest, const char* src)
|
|
|
|
{
|
|
|
|
char* s = dest;
|
|
|
|
for (; *src; dest++, src++) *dest = *src;
|
|
|
|
*dest = 0;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* strcat(char* dest, const char* src)
|
|
|
|
{
|
|
|
|
char* s = dest;
|
|
|
|
while (*dest) dest++;
|
|
|
|
for (; *src; dest++, src++) *dest = *src;
|
|
|
|
*dest = 0;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2023-04-23 08:53:48 +00:00
|
|
|
char* strncpy(char* dest, const char* src, usize max)
|
2023-03-12 14:20:44 +00:00
|
|
|
{
|
2023-04-23 08:53:48 +00:00
|
|
|
usize i;
|
2023-03-12 14:20:44 +00:00
|
|
|
for (i = 0; i < max && src[i] != 0; i++) dest[i] = src[i];
|
|
|
|
for (; i < max; i++) dest[i] = 0;
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2023-04-23 08:53:48 +00:00
|
|
|
char* strncat(char* dest, const char* src, usize max)
|
2023-03-12 14:20:44 +00:00
|
|
|
{
|
2023-04-23 08:53:48 +00:00
|
|
|
usize len = strlen(dest);
|
|
|
|
usize i;
|
2023-03-12 14:20:44 +00:00
|
|
|
|
|
|
|
for (i = 0; i < max && *(src + i); i++) *(dest + len + i) = *(src + i);
|
|
|
|
|
|
|
|
*(dest + len + i) = '\0';
|
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2023-01-06 15:20:35 +00:00
|
|
|
char* strchr(const char* str, int c)
|
|
|
|
{
|
|
|
|
while (*str && *str != c) str++;
|
|
|
|
if (*str) return const_cast<char*>(str);
|
|
|
|
return NULL;
|
|
|
|
}
|
2023-02-27 14:03:22 +00:00
|
|
|
|
2023-03-11 00:13:44 +00:00
|
|
|
char* strrchr(const char* str, int c)
|
|
|
|
{
|
|
|
|
const char* s = str + strlen(str);
|
|
|
|
while (s != str && *s != (char)c) s--;
|
|
|
|
if (s != str) return const_cast<char*>(s);
|
|
|
|
if (*s == (char)c) return const_cast<char*>(s);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2023-02-27 14:03:22 +00:00
|
|
|
usize strlcpy(char* dest, const char* src, usize len)
|
|
|
|
{
|
|
|
|
usize src_len = strlen(src);
|
|
|
|
usize copy_len = src_len;
|
|
|
|
if (len == 0) return src_len;
|
|
|
|
if (src_len >= (len - 1)) copy_len = len - 1;
|
|
|
|
memcpy(dest, src, copy_len);
|
|
|
|
dest[copy_len] = 0;
|
|
|
|
return src_len;
|
|
|
|
}
|
2023-03-10 20:32:18 +00:00
|
|
|
|
|
|
|
usize strcspn(const char* str, const char* reject)
|
|
|
|
{
|
|
|
|
const char* s = str;
|
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
const char* rp = reject;
|
|
|
|
while (*rp)
|
|
|
|
{
|
|
|
|
if (*s == *rp) return (usize)(s - str);
|
|
|
|
rp++;
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
return (usize)(s - str);
|
|
|
|
}
|
|
|
|
|
|
|
|
usize strspn(const char* str, const char* accept)
|
|
|
|
{
|
|
|
|
const char* s = str;
|
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
const char* ap = accept;
|
|
|
|
bool match = false;
|
|
|
|
while (*ap)
|
|
|
|
{
|
|
|
|
if (*s == *ap)
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ap++;
|
|
|
|
}
|
|
|
|
if (!match) return (usize)(s - str);
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
return (usize)(s - str);
|
|
|
|
}
|
|
|
|
|
2023-05-20 14:37:07 +00:00
|
|
|
char* strtok_r(char* str, const char* delim, char** savep)
|
2023-03-10 20:32:18 +00:00
|
|
|
{
|
2023-05-20 14:37:07 +00:00
|
|
|
auto& s = *savep;
|
2023-03-10 20:32:18 +00:00
|
|
|
if (str) s = str;
|
|
|
|
if (!s) return nullptr;
|
|
|
|
|
|
|
|
if (*s)
|
|
|
|
{
|
|
|
|
usize skip = strspn(s, delim);
|
|
|
|
s += skip;
|
|
|
|
|
|
|
|
if (*s == 0) return nullptr;
|
|
|
|
|
|
|
|
usize use = strcspn(s, delim);
|
|
|
|
char* result = s;
|
|
|
|
|
|
|
|
if (s[use] != 0)
|
|
|
|
{
|
|
|
|
s[use] = 0;
|
|
|
|
s += (use + 1);
|
|
|
|
}
|
|
|
|
else { s = nullptr; }
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
2023-04-12 16:42:25 +00:00
|
|
|
|
2023-05-20 14:37:07 +00:00
|
|
|
char* strtok(char* str, const char* delim)
|
|
|
|
{
|
|
|
|
static char* s;
|
|
|
|
return strtok_r(str, delim, &s);
|
|
|
|
}
|
|
|
|
|
2023-04-12 16:42:25 +00:00
|
|
|
char* strpbrk(const char* s, const char* accept)
|
|
|
|
{
|
|
|
|
usize index = strcspn(s, accept);
|
|
|
|
|
|
|
|
const char* ptr = s + index;
|
|
|
|
|
|
|
|
if (*ptr) return const_cast<char*>(ptr);
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
2023-07-10 13:30:05 +00:00
|
|
|
|
|
|
|
char* strstr(const char* haystack, const char* needle)
|
|
|
|
{
|
|
|
|
const char* i = haystack; // keeps track of the current haystack position
|
|
|
|
const char* j = needle; // keeps track of the current needle position
|
|
|
|
const char* k = haystack; // keeps track of the first matched character
|
|
|
|
|
|
|
|
while (*i)
|
|
|
|
{
|
|
|
|
if (*j == 0) return const_cast<char*>(k);
|
|
|
|
if (*i != *j)
|
|
|
|
{
|
|
|
|
j = needle;
|
|
|
|
k = i + 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
j++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*j == 0) return const_cast<char*>(k);
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
2023-07-22 09:58:28 +00:00
|
|
|
|
|
|
|
int strcasecmp(const char* a, const char* b)
|
|
|
|
{
|
|
|
|
while (*a && (_tolower(*a) == _tolower(*b)))
|
|
|
|
{
|
|
|
|
a++;
|
|
|
|
b++;
|
|
|
|
}
|
|
|
|
return _tolower(*(const u8*)a) - _tolower(*(const u8*)b);
|
|
|
|
}
|
|
|
|
|
|
|
|
int strncasecmp(const char* a, const char* b, usize max)
|
|
|
|
{
|
|
|
|
const char* s = a;
|
|
|
|
while (*a && (_tolower(*a) == _tolower(*b)) && (usize)(a - s) < (max - 1))
|
|
|
|
{
|
|
|
|
a++;
|
|
|
|
b++;
|
|
|
|
}
|
|
|
|
return _tolower(*(const u8*)a) - _tolower(*(const u8*)b);
|
|
|
|
}
|
2023-01-02 12:07:29 +00:00
|
|
|
}
|