2022-06-06 01:30:01 +00:00
|
|
|
|
2022-08-10 03:13:47 +00:00
|
|
|
void *memcpy(void *restrict to, void const *restrict from, size_t n) {
|
|
|
|
u8 *restrict dst = to;
|
|
|
|
u8 const *restrict src = from;
|
2022-06-03 02:02:19 +00:00
|
|
|
while (n--) {
|
2022-08-10 03:13:47 +00:00
|
|
|
*dst++ = *src++;
|
2022-06-03 02:02:19 +00:00
|
|
|
}
|
2022-08-10 03:13:47 +00:00
|
|
|
return dst;
|
2022-06-02 23:36:04 +00:00
|
|
|
}
|
|
|
|
|
2022-08-10 03:13:47 +00:00
|
|
|
void *memmove(void *to, const void *from, size_t n) {
|
|
|
|
u8 *dst = to;
|
|
|
|
u8 const *src = from;
|
|
|
|
if (src != dst) {
|
|
|
|
if (src < dst) {
|
2022-06-08 02:42:08 +00:00
|
|
|
// reverse copy
|
2022-08-10 03:13:47 +00:00
|
|
|
for (size_t i = n; i--;) dst[i] = src[i];
|
2022-06-08 02:42:08 +00:00
|
|
|
} else {
|
|
|
|
// normal copy
|
2022-08-10 03:13:47 +00:00
|
|
|
for (size_t i = 0; i < n; i++) dst[i] = src[i];
|
2022-06-08 02:42:08 +00:00
|
|
|
}
|
|
|
|
}
|
2022-08-10 03:13:47 +00:00
|
|
|
return dst;
|
2022-06-02 13:08:59 +00:00
|
|
|
}
|
2022-06-02 23:36:04 +00:00
|
|
|
|
2022-08-10 03:13:47 +00:00
|
|
|
char *strcpy(char *restrict dst, char const *restrict src) {
|
|
|
|
size_t i = 0;
|
|
|
|
for(i = 0; src[i]; ++i) {
|
|
|
|
dst[i] = src[i];
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
2022-08-10 03:13:47 +00:00
|
|
|
dst[i] = 0;
|
|
|
|
return dst;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
|
|
|
|
2022-08-10 03:13:47 +00:00
|
|
|
char *strncpy(char *restrict dst, char const *restrict src, size_t n) {
|
|
|
|
size_t i;
|
|
|
|
for(i = 0; i != n && src[i]; ++i) {
|
|
|
|
dst[i] = src[i];
|
2022-06-03 02:02:19 +00:00
|
|
|
}
|
2022-08-10 03:13:47 +00:00
|
|
|
for(; i != n; ++i) {
|
|
|
|
dst[i] = 0;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
2022-08-10 03:13:47 +00:00
|
|
|
return dst;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-10 03:13:47 +00:00
|
|
|
char *strcat(char *restrict dst, const char *restrict src) {
|
|
|
|
size_t start = strlen(dst);
|
|
|
|
return strcpy(dst+start, src);
|
2022-06-07 09:26:13 +00:00
|
|
|
}
|
|
|
|
|
2022-08-10 03:13:47 +00:00
|
|
|
char *strncat(char *restrict dst, char const *restrict src, size_t n) {
|
|
|
|
size_t start = strlen(dst);
|
|
|
|
strncpy(dst+start, src, n);
|
|
|
|
return dst;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
2022-06-02 23:36:04 +00:00
|
|
|
|
2022-06-06 01:30:01 +00:00
|
|
|
|
2022-08-10 03:13:47 +00:00
|
|
|
int memcmp(void const *p1, void const *p2, size_t n) {
|
|
|
|
u8 const *s1 = p1;
|
|
|
|
u8 const *s2 = p2;
|
|
|
|
size_t i;
|
|
|
|
for(i = 0; i != n; ++i) {
|
|
|
|
if(s1[i] != s2[i]) break;
|
|
|
|
}
|
|
|
|
if(i != n) {
|
|
|
|
if(s1[i] < s2[i]) return -1;
|
|
|
|
if(s1[i] > s2[i]) return 1;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
2022-06-03 02:02:19 +00:00
|
|
|
return 0;
|
2022-06-02 23:36:04 +00:00
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
void *memset(void *s, int c, size_t n) {
|
2022-08-05 08:17:24 +00:00
|
|
|
u8 *restrict buf = s;
|
2022-06-07 09:26:13 +00:00
|
|
|
while (n--) {
|
|
|
|
*buf++ = c;
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2022-08-10 03:13:47 +00:00
|
|
|
int strcmp(char const *s1, char const *s2) {
|
|
|
|
size_t i;
|
|
|
|
for(i = 0; s1[i] && s2[i]; ++i) {
|
|
|
|
if(s1[i] != s2[i]) break;
|
|
|
|
}
|
|
|
|
if(s1[i] < s2[i]) return -1;
|
|
|
|
if(s1[i] > s2[i]) return +1;
|
|
|
|
return 0;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
int strncmp(const char *s1, const char *s2, size_t n) {
|
2022-08-10 03:13:47 +00:00
|
|
|
size_t i;
|
|
|
|
for(i = 0; i != n && s1[i] && s2[i]; ++i) {
|
|
|
|
if(s1[i] != s2[i]) break;
|
|
|
|
}
|
|
|
|
if(s1[i] < s2[i]) return -1;
|
|
|
|
if(s1[i] > s2[i]) return +1;
|
|
|
|
return 0;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
int strcoll(const char *s1, const char *s2) {
|
2022-06-06 01:30:01 +00:00
|
|
|
return strcmp(s1, s2);
|
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
// TODO: I don't quite understand the intent nor use behind this function
|
|
|
|
// so I'm just going to ignore locales for now.
|
|
|
|
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) {
|
2022-06-06 01:30:01 +00:00
|
|
|
size_t len = strlen(s2);
|
|
|
|
if(s1 != NULL && n != 0) {
|
2022-06-06 01:38:36 +00:00
|
|
|
for(size_t i = 0; i != n; ++i) {
|
2022-06-06 01:30:01 +00:00
|
|
|
*s1 = *s2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
void *memchr(const void *ptr, int c, size_t n) {
|
|
|
|
const char *s = ptr;
|
|
|
|
for(size_t i = 0; i != n; ++i) {
|
|
|
|
if(s[i] == c) {
|
|
|
|
// Casting away const because clang warnings
|
|
|
|
return (void *)(s+i);
|
|
|
|
}
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
2022-06-07 09:26:13 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *strchr(const char *s, int c) {
|
|
|
|
do {
|
|
|
|
if(*s == c) return (char *)s;
|
|
|
|
} while(*s++);
|
|
|
|
return NULL;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
size_t strspn(const char *s1, const char *s2) {
|
|
|
|
size_t i = 0;
|
|
|
|
for(; *s1; ++s1) {
|
|
|
|
if(strchr(s2, *s1) == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
return i;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
size_t strcspn(const char *s1, const char *s2) {
|
2022-06-06 01:30:01 +00:00
|
|
|
size_t i = 0;
|
2022-06-07 09:26:13 +00:00
|
|
|
for(; *s1; ++s1) {
|
2022-06-06 01:30:01 +00:00
|
|
|
if(strchr(s2, *s1) != NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
char *strpbrk(const char *s1, const char *s2) {
|
2022-06-06 01:30:01 +00:00
|
|
|
while(*s1) {
|
|
|
|
if(strchr(s2, *s1) == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++s1;
|
|
|
|
}
|
|
|
|
return (char *)s1;
|
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
char *strrchr(const char *s, int c) {
|
|
|
|
char const *last = NULL;
|
|
|
|
for(; *s != 0; ++s) {
|
|
|
|
if(*s == c) last = s;
|
|
|
|
}
|
|
|
|
return (char *)last;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *strstr(const char *s1, const char *s2) {
|
|
|
|
if(*s2 == 0) return (char *)s1;
|
2022-06-06 01:30:01 +00:00
|
|
|
size_t len = strlen(s2);
|
2022-06-07 09:26:13 +00:00
|
|
|
for(; *s1 != 0; ++s1) {
|
|
|
|
if(strncmp(s1, s2, len) == 0) return (char *)s1;
|
2022-06-06 01:30:01 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-06-07 09:26:13 +00:00
|
|
|
// TODO: there may be restrict-related UB
|
|
|
|
char *strtok(char *restrict s1, const char *restrict s2) {
|
2022-06-08 02:36:49 +00:00
|
|
|
static char *str;
|
|
|
|
return strtok_r(s1, s2, &str);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *strtok_r(char *restrict s1, const char *restrict s2, char **restrict ctx) {
|
|
|
|
if(s1 != NULL) *ctx = s1;
|
|
|
|
if(*ctx == NULL) return NULL;
|
2022-06-07 09:26:13 +00:00
|
|
|
|
2022-06-08 02:36:49 +00:00
|
|
|
size_t junk_len = strspn(*ctx, s2);
|
|
|
|
char *tok_start = *ctx + junk_len;
|
2022-06-07 09:26:13 +00:00
|
|
|
if(*tok_start == 0) {
|
2022-06-08 02:36:49 +00:00
|
|
|
*ctx = NULL;
|
2022-06-07 09:26:13 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-06-08 02:36:49 +00:00
|
|
|
size_t tok_len = strcspn(*ctx, s2);
|
2022-06-07 09:26:13 +00:00
|
|
|
|
|
|
|
char *tok_end = tok_start + tok_len;
|
|
|
|
*tok_end = 0;
|
2022-06-08 02:36:49 +00:00
|
|
|
*ctx = tok_end+1;
|
2022-06-07 09:26:13 +00:00
|
|
|
|
|
|
|
return tok_start;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *strerror(int errnum) {
|
2022-06-06 01:30:01 +00:00
|
|
|
switch(errnum) {
|
|
|
|
case 0: return "No errors";
|
|
|
|
case EDOM: return "Value is out of domain of the function";
|
|
|
|
case EILSEQ: return "Illegal byte sequence";
|
|
|
|
case ERANGE: return "Value is out of range";
|
|
|
|
}
|
|
|
|
return "Unkown error";
|
|
|
|
}
|
|
|
|
|
2022-06-02 23:36:04 +00:00
|
|
|
size_t strlen(const char *s) {
|
2022-06-03 02:02:19 +00:00
|
|
|
size_t i = 0;
|
|
|
|
while (s[i]) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return i;
|
2022-06-02 23:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t strnlen_s(const char *s, size_t maxsize) {
|
2022-06-06 00:16:44 +00:00
|
|
|
if (s == NULL) return 0;
|
2022-06-03 02:02:19 +00:00
|
|
|
size_t i = 0;
|
|
|
|
while (s[i] && i < maxsize) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return i;
|
2022-06-02 23:36:04 +00:00
|
|
|
}
|
2022-06-24 01:45:55 +00:00
|
|
|
|
|
|
|
char *strdup(const char *str1) {
|
2022-06-24 03:54:51 +00:00
|
|
|
if(str1 == NULL) return NULL;
|
2022-06-24 01:45:55 +00:00
|
|
|
size_t len = strlen(str1);
|
|
|
|
char *copy = calloc(len+1, 1);
|
|
|
|
strcpy(copy, str1);
|
|
|
|
return copy;
|
|
|
|
}
|