mirror of
https://github.com/encounter/osdev.git
synced 2026-03-30 11:33:54 -07:00
131 lines
3.2 KiB
C
131 lines
3.2 KiB
C
#include "string.h"
|
|
#include "stdio.h"
|
|
|
|
#include <limits.h>
|
|
#include <malloc.h>
|
|
|
|
#define _ALIGN (sizeof(size_t))
|
|
#define _ONES ((size_t) - 1 / UCHAR_MAX)
|
|
#define _HIGHS (_ONES * (UCHAR_MAX / 2 + 1))
|
|
#define _HASZERO(x) (((x) - _ONES) & ~(x) & _HIGHS)
|
|
#define _SS (sizeof(size_t))
|
|
|
|
// One measly byte at a time...
|
|
void *memcpy(void *restrict destination, const void *restrict source, size_t num) {
|
|
char *s1 = (char *) destination;
|
|
const char *s2 = (const char *) source;
|
|
|
|
while (num--) {
|
|
*s1++ = *s2++;
|
|
}
|
|
|
|
return destination;
|
|
}
|
|
|
|
void *memmove(void *destination, const void *source, size_t num) {
|
|
char *dest = (char *) destination;
|
|
const char *src = (const char *) source;
|
|
if (dest <= src) {
|
|
while (num--) *dest++ = *src++;
|
|
} else {
|
|
src += num;
|
|
dest += num;
|
|
while (num--) *--dest = *--src;
|
|
}
|
|
return destination;
|
|
}
|
|
|
|
void *memset(void *const ptr, const int value, size_t num) {
|
|
const unsigned char b = (unsigned char) value;
|
|
unsigned char *p = (unsigned char *) ptr;
|
|
|
|
while (num--) {
|
|
*p++ = b;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
int memcmp(const void *const s1, const void *const s2, size_t n) {
|
|
const unsigned char *p1 = s1;
|
|
const unsigned char *p2 = s2;
|
|
|
|
while (n--) {
|
|
const int r = *p1++ - *p2++;
|
|
if (r) return r;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *memchr(const void *src, int c, size_t n) {
|
|
const unsigned char *s = src;
|
|
c = (unsigned char) c;
|
|
#ifdef __GNUC__
|
|
for (; ((uintptr_t) s & _ALIGN) && n && *s != c; s++, n--);
|
|
if (n && *s != c) {
|
|
typedef size_t __attribute__((__may_alias__)) word;
|
|
const word *w;
|
|
size_t k = _ONES * c;
|
|
for (w = (const void *) s; n >= _SS && !_HASZERO(*w ^ k); w++, n -= _SS);
|
|
s = (const void *) w;
|
|
}
|
|
#endif
|
|
for (; n && *s != c; s++, n--);
|
|
return n ? (void *) s : 0;
|
|
}
|
|
|
|
size_t strlen(const char *str) {
|
|
const char *a = str;
|
|
const size_t *w;
|
|
for (; (uintptr_t) str % _ALIGN; str++) if (!*str) return str - a;
|
|
for (w = (const void *) str; !_HASZERO(*w); w++);
|
|
for (str = (const void *) w; *str; str++);
|
|
return str - a;
|
|
}
|
|
|
|
size_t strnlen(const char *s, size_t n) {
|
|
const char *p = memchr(s, 0, n);
|
|
return p ? p - s : n;
|
|
}
|
|
|
|
int strcmp(const char *const str1, const char *const str2) {
|
|
const unsigned char *p1 = (unsigned char *) str1;
|
|
const unsigned char *p2 = (unsigned char *) str2;
|
|
|
|
while (*p1 != '\0' && *p1 == *p2) {
|
|
p1++, p2++;
|
|
}
|
|
|
|
return *p1 - *p2;
|
|
}
|
|
|
|
int strncmp(const char *str1, const char *str2, size_t num) {
|
|
while (*str1 && num && (*str1 == *str2)) {
|
|
++str1;
|
|
++str2;
|
|
--num;
|
|
}
|
|
return num == 0 ? 0 : *(unsigned char *) str1 - *(unsigned char *) str2;
|
|
}
|
|
|
|
char *strcpy(char *destination, const char *source) {
|
|
char *rc = destination;
|
|
while ((*destination++ = *source++));
|
|
return rc;
|
|
}
|
|
|
|
char *strncpy(char *restrict s1, const char *restrict s2, size_t n) {
|
|
char *rc = s1;
|
|
while ((n > 0) && (*s1++ = *s2++)) --n;
|
|
while (n-- > 1) *s1++ = '\0';
|
|
return rc;
|
|
}
|
|
|
|
char *strdup(char *str) {
|
|
size_t len = strlen(str) + 1;
|
|
char *new = malloc(len);
|
|
if (new == NULL) return NULL;
|
|
return memcpy(new, str, len);
|
|
}
|