varch/source/02_vstd/vstring.c
2024-04-22 00:09:51 +08:00

620 lines
10 KiB
C

#include "vstring.h"
#include "vctype.h"
#include "vstdlib.h"
void *v_memcpy(void *dest, const void *src, size_t n)
{
char *dst = dest;
const char *s = src;
while (n--)
{
*dst++ = *s++;
}
return dest;
}
void *v_mempcpy(void *dest, const void *src, size_t n)
{
char *p1 = (char *)dest;
const char *p2 = (const char *)src;
size_t i;
for (i = 0; i < n; i++)
{
p1[i] = p2[i];
}
return (void *)(p1 + i);
}
void *v_memmove(void *dest, const void *src, size_t n)
{
char *dst = dest;
const char *s = src;
if (dst <= s)
{
while (n--)
{
*dst++ = *s++;
}
}
else
{
dst += n;
s += n;
while (n--)
{
*--dst = *--s;
}
}
return dest;
}
void *v_memccpy(void *dest, const void *src, int c, size_t n)
{
char *dst = dest;
const char *s = src;
while (n--)
{
*dst++ = *s;
if (*s++ == c)
{
return dst;
}
}
return NULL;
}
void *v_memset(void *s, int c, size_t n)
{
char *p = s;
while (n--)
{
*p++ = (char) c;
}
return s;
}
int v_memcmp(const void *s1, const void *s2, size_t n)
{
const unsigned char *p1 = s1, *p2 = s2;
for (size_t i = 0; i < n; ++i, ++p1, ++p2)
{
if (*p1 != *p2)
{
return (*p1 < *p2) ? -1 : 1;
}
}
return 0;
}
void *v_memchr(const void *s, int c, size_t n)
{
const unsigned char *p = s;
for (size_t i = 0; i < n; ++i, ++p)
{
if (*p == (unsigned char) c)
{
return (void *) p;
}
}
return NULL;
}
void *v_memrchr(const void *s, int c, size_t n)
{
const unsigned char *p = (const unsigned char *) s + n - 1;
for (; p >= (const unsigned char *) s; --p)
{
if (*p == (unsigned char) c)
{
return (void *) p;
}
}
return NULL;
}
void *v_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
{
const char *p1 = (const char *)haystack;
const char *p2 = (const char *)needle;
size_t i;
if (needlelen == 0)
{
return (void *)p1;
}
if (haystacklen < needlelen)
{
return NULL;
}
for (i = 0; i <= haystacklen - needlelen; i++)
{
if (p1[i] == *p2 && v_memcmp(p1 + i, p2, needlelen) == 0)
{
return (void *)(p1 + i);
}
}
return NULL;
}
void *v_memfrob(void *s, size_t n)
{
unsigned char *p = (unsigned char *)s;
for (size_t i = 0; i < n; i++)
{
p[i] ^= 42;
}
return s;
}
char *v_strcpy(char *dest, const char *src)
{
char *p = dest;
while (*src)
{
*p++ = *src++;
}
*p = '\0';
return dest;
}
char *v_strncpy(char *dest, const char *src, size_t n)
{
char *p = dest;
size_t i = 0;
while (i < n && *src)
{
*p++ = *src++;
++i;
}
while (i < n)
{
*p++ = '\0';
++i;
}
return dest;
}
size_t v_strlen(const char *s)
{
const char *p = s;
while (*p)
{
++p;
}
return p - s;
}
size_t v_strnlen(const char *s, size_t n)
{
const char *p = s;
size_t i;
for (i = 0; i < n && *p != '\0'; i++, p++);
return i;
}
char *v_strcat(char *dest, const char *src)
{
char *p = dest + v_strlen(dest);
while (*src)
{
*p++ = *src++;
}
*p = '\0';
return dest;
}
int v_strcmp(const char *s1, const char *s2)
{
while (*s1 && *s1 == *s2)
{
++s1;
++s2;
}
return *s1 - *s2;
}
int v_strncmp(const char *s1, const char *s2, size_t n)
{
size_t i = 0;
while (i < n && *s1 && *s1 == *s2)
{
++s1;
++s2;
++i;
}
if (i == n)
{
return 0;
}
else
{
return *s1 - *s2;
}
}
static int v_strcoll_helper(char c1, char c2)
{
if (c1 < c2)
{
return -1;
}
else if (c1 > c2)
{
return 1;
}
else
{
return 0;
}
}
int v_strcoll(const char *s1, const char *s2)
{
while (*s1 && *s1 == *s2)
{
++s1;
++s2;
}
return v_strcoll_helper(*s1, *s2);
}
size_t v_strxfrm(char *dest, const char *src, size_t n)
{
size_t i = 0;
while (*src && i < n)
{
*dest = *src;
++dest;
++src;
++i;
}
if (i == n)
{
*dest = '\0';
return n;
}
else
{
*dest = '\0';
return i;
}
}
char *v_strdup(const char *s)
{
size_t len = v_strlen(s) + 1;
char *p = v_malloc(len);
if (p == NULL)
{
return NULL;
}
return (char *) v_memcpy(p, s, len);
}
char *v_strndup(const char *str, size_t n)
{
size_t len = v_strlen(str);
if (n < len)
{
len = n;
}
char *new_str = (char *) v_malloc(len + 1);
if (new_str == NULL) {
return NULL;
}
v_memcpy(new_str, str, len);
new_str[len] = '\0';
return new_str;
}
char *v_strchr(const char *str, int ch)
{
while (*str != '\0' && *str != ch)
{
str++;
}
if (*str == ch)
{
return (char *) str;
}
else
{
return NULL;
}
}
char *v_strrchr(const char *str, int ch)
{
const char *last = NULL;
while (*str != '\0')
{
if (*str == ch)
{
last = str;
}
str++;
}
if (*str == ch)
{
return (char *) str;
}
else
{
return (char *) last;
}
}
char *v_strchrnul(const char *str, int ch)
{
while (*str != '\0' && *str != ch)
{
str++;
}
return (char *) str;
}
size_t v_strcspn(const char *str, const char *charset)
{
size_t len = 0;
while (*str != '\0')
{
const char *p = charset;
while (*p != '\0')
{
if (*str == *p)
{
return len;
}
p++;
}
str++;
len++;
}
return len;
}
char *v_strpbrk(const char *str, const char *charset)
{
while (*str != '\0')
{
const char *p = charset;
while (*p != '\0')
{
if (*str == *p)
{
return (char *) str;
}
p++;
}
str++;
}
return NULL;
}
char *v_strstr(const char *str, const char *substr)
{
if (*substr == '\0')
{
return (char *) str;
}
while (*str != '\0')
{
const char *p = str;
const char *q = substr;
while (*p != '\0' && *q != '\0' && *p == *q)
{
p++;
q++;
}
if (*q == '\0')
{
return (char *) str;
}
str++;
}
return NULL;
}
char *v_strrstr(const char *str, const char *substr)
{
size_t len = v_strlen(substr);
if (len == 0) {
return (char *) (str + v_strlen(str));
}
const char *end = str + v_strlen(str) - len;
for (const char *p = end; p >= str; p--)
{
if (v_strncmp(p, substr, len) == 0)
{
return (char *) p;
}
}
return NULL;
}
char *v_strtok(char *str, const char *delim)
{
static char *last_str = NULL;
static const char *last_delim = NULL;
char *ret = NULL;
if (str != NULL)
{
last_str = str;
}
else if (last_str == NULL)
{
return NULL;
}
if (delim != NULL)
{
last_delim = delim;
}
else if (last_delim == NULL)
{
return NULL;
}
ret = last_str;
while (*last_str != '\0')
{
const char *p = last_delim;
while (*p != '\0' && *p != *last_str)
{
p++;
}
if (*p != '\0')
{
*last_str = '\0';
last_str++;
break;
}
last_str++;
}
return ret;
}
char *v_strtok_r(char *str, const char *delim, char **saveptr)
{
char *last_str = NULL;
const char *last_delim = NULL;
char *ret = NULL;
if (str != NULL)
{
last_str = str;
}
else if (*saveptr == NULL)
{
return NULL;
}
else
{
last_str = *saveptr;
}
if (delim != NULL)
{
last_delim = delim;
}
else if (*saveptr == NULL)
{
return NULL;
}
else
{
last_delim = *saveptr;
}
ret = last_str;
while (*last_str != '\0')
{
const char *p = last_delim;
while (*p != '\0' && *p != *last_str)
{
p++;
}
if (*p != '\0')
{
*last_str = '\0';
last_str++;
break;
}
last_str++;
}
*saveptr = last_str;
return ret;
}
char *v_strcasestr(const char *haystack, const char *needle)
{
const char *p1 = haystack;
while (*p1 != '\0')
{
const char *p2 = needle;
const char *p3 = p1;
while (*p2 != '\0' && v_tolower(*p2) == v_tolower(*p3))
{
p2++;
p3++;
}
if (*p2 == '\0')
{
return (char *)p1;
}
p1++;
}
return NULL;
}
char *v_strsep(char **stringp, const char *delim)
{
char *p, *start;
start = *stringp;
p = (start != NULL) ? v_strpbrk(start, delim) : NULL;
if (p == NULL)
{
*stringp = NULL;
}
else
{
*p = '\0';
*stringp = p + 1;
}
return start;
}
char *v_stpcpy(char *dest, const char *src)
{
while ((*dest++ = *src++));
return dest - 1;
}
char *v_stpncpy(char *dest, const char *src, size_t n)
{
char *p = dest;
while (n-- && *src)
{
*p++ = *src++;
}
while (n--)
{
*p++ = '\0';
}
return p;
}
int v_strverscmp(const char *s1, const char *s2)
{
const unsigned char *p1 = (const unsigned char *)s1;
const unsigned char *p2 = (const unsigned char *)s2;
int num1 = 0, num2 = 0;
while (*p1 || *p2)
{
while (v_isdigit(*p1))
{
num1 = num1 * 10 + (*p1 - '0');
p1++;
}
while (v_isdigit(*p2))
{
num2 = num2 * 10 + (*p2 - '0');
p2++;
}
if (num1 != num2)
{
return num1 > num2 ? 1 : -1;
}
if (*p1 != *p2)
{
return *p1 > *p2 ? 1 : -1;
}
if (*p1)
{
p1++;
}
if (*p2)
{
p2++;
}
num1 = num2 = 0;
}
return 0;
}