2024-02-01 17:48:55 +00:00
|
|
|
#include "memory.h"
|
2024-01-27 07:14:19 +00:00
|
|
|
#include <lib.h>
|
2024-01-27 08:01:34 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
int memcmp(const void *restrict vl, const void *restrict vr, unsigned long n) {
|
2024-01-31 18:11:47 +00:00
|
|
|
const unsigned char *l = vl, *r = vr;
|
|
|
|
for (; n && *l == *r; n--, l++, r++);
|
|
|
|
return n ? *l-*r : 0;
|
2024-01-27 08:01:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *memcpy(void *restrict dest, const void *restrict src, unsigned long n) {
|
|
|
|
char *d = dest;
|
2024-01-31 18:11:47 +00:00
|
|
|
const char *s = src;
|
|
|
|
for (; n; n--) *d++ = *s++;
|
|
|
|
return dest;
|
2024-01-27 08:01:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *memmove(void *dest, const void *src, unsigned long n) {
|
2024-01-31 18:11:47 +00:00
|
|
|
char *d = dest;
|
|
|
|
const char *s = src;
|
2024-01-27 08:01:34 +00:00
|
|
|
|
2024-01-31 18:11:47 +00:00
|
|
|
if (d==s) return d;
|
2024-01-27 08:01:34 +00:00
|
|
|
|
2024-01-31 18:11:47 +00:00
|
|
|
if (d<s) {
|
|
|
|
for (; n; n--) *d++ = *s++;
|
|
|
|
} else {
|
|
|
|
while (n) n--, d[n] = s[n];
|
|
|
|
}
|
2024-01-27 08:01:34 +00:00
|
|
|
|
2024-01-31 18:11:47 +00:00
|
|
|
return dest;
|
2024-01-27 08:01:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *memset(void *restrict dest, int c, unsigned long n) {
|
2024-01-31 18:11:47 +00:00
|
|
|
unsigned char *d = dest;
|
|
|
|
for (; n; n--) *d++ = c;
|
|
|
|
return dest;
|
2024-01-27 08:01:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int strncmp(const char *restrict lhs, const char *restrict rhs, unsigned long n) {
|
2024-01-27 07:14:19 +00:00
|
|
|
const unsigned char *l=(void *)lhs, *r=(void *)rhs;
|
|
|
|
if (!n--) return 0;
|
|
|
|
for (; *l && *r && n && *l == *r ; l++, r++, n--);
|
|
|
|
return *l - *r;
|
|
|
|
}
|
|
|
|
|
2024-01-27 08:38:27 +00:00
|
|
|
char *strcpy(char *restrict dest, const char *restrict src) {
|
2024-02-01 03:30:35 +00:00
|
|
|
char *d = dest;
|
|
|
|
for (; (*d = *src); d++, src++);
|
2024-01-27 08:38:27 +00:00
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *strncpy(char *restrict dest, const char *restrict src, unsigned long n) {
|
2024-02-01 03:30:35 +00:00
|
|
|
char *d = dest;
|
|
|
|
for (; (*d = *src) && n; d++, src++, n--);
|
|
|
|
memset(d, 0, n);
|
2024-01-27 08:38:27 +00:00
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2024-01-30 02:10:29 +00:00
|
|
|
size_t strlen(const char *str) {
|
2024-01-31 18:11:47 +00:00
|
|
|
const char *p;
|
2024-02-01 03:30:35 +00:00
|
|
|
for (p = str; *p != 0; p++) {}
|
2024-01-31 18:11:47 +00:00
|
|
|
return p - str;
|
2024-01-30 02:10:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *strcat(char *restrict dst, const char *restrict src) {
|
2024-01-31 18:11:47 +00:00
|
|
|
strcpy(dst + strlen(dst), src);
|
|
|
|
return dst;
|
2024-01-30 02:10:29 +00:00
|
|
|
}
|
|
|
|
|
2024-01-27 08:01:34 +00:00
|
|
|
int isspace(int c) {
|
2024-01-31 18:11:47 +00:00
|
|
|
switch (c) {
|
|
|
|
case ' ':
|
|
|
|
case '\t':
|
|
|
|
case '\v':
|
|
|
|
case '\f':
|
|
|
|
case '\r':
|
|
|
|
case '\n':
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
2024-01-27 07:14:19 +00:00
|
|
|
}
|
2024-01-27 08:01:34 +00:00
|
|
|
|
|
|
|
int isdigit(int c) {
|
2024-01-31 18:11:47 +00:00
|
|
|
return c - '0' > -1 && c - '0' < 10;
|
2024-01-27 08:01:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define ATOX(name, type) \
|
2024-02-01 03:30:35 +00:00
|
|
|
type name(const char *s) { \
|
|
|
|
for (; isspace(*s); s++); \
|
2024-01-31 18:11:47 +00:00
|
|
|
int neg = 0; \
|
|
|
|
switch (*s) { \
|
|
|
|
case '-': \
|
|
|
|
neg = 1; \
|
|
|
|
/* FALLTHRU */ \
|
|
|
|
case '+': \
|
|
|
|
s++; \
|
|
|
|
break; \
|
|
|
|
} \
|
|
|
|
type num = 0; \
|
|
|
|
for (; *s == '0'; s++); \
|
|
|
|
for (; isdigit(*s); s++) { \
|
|
|
|
num *= 10; \
|
|
|
|
num += *s - '0'; \
|
|
|
|
} \
|
|
|
|
return num * (neg ? -1 : 1); \
|
|
|
|
}
|
2024-01-27 08:01:34 +00:00
|
|
|
|
|
|
|
ATOX(atoi, int)
|
|
|
|
ATOX(atol, long int)
|
|
|
|
ATOX(atoll, long long int)
|
|
|
|
|
|
|
|
char itoc(int i) {
|
2024-02-01 03:30:35 +00:00
|
|
|
if (i < 10) {
|
2024-01-27 08:01:34 +00:00
|
|
|
return '0' + i;
|
|
|
|
} else {
|
|
|
|
return 'a' + (i - 10);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int ctoi(char c) {
|
2024-02-01 03:30:35 +00:00
|
|
|
if (c < 'A') {
|
2024-01-27 08:01:34 +00:00
|
|
|
return c - '0';
|
2024-02-01 03:30:35 +00:00
|
|
|
} else if (c < 'a') {
|
2024-01-27 08:01:34 +00:00
|
|
|
return c - 'A' + 10;
|
|
|
|
} else {
|
|
|
|
return c - 'a' + 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-01 20:53:11 +00:00
|
|
|
static char fs_endings[] = {'K', 'M', 'G', 'T', 'P'};
|
|
|
|
|
|
|
|
static size_t nth_pow(size_t i, size_t e) {
|
|
|
|
size_t a = i;
|
|
|
|
while(--e)
|
|
|
|
a *= i;
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char nth_digit(size_t bytes, size_t place) {
|
|
|
|
while (1) {
|
|
|
|
if (bytes < nth_pow(10, place))
|
|
|
|
break;
|
|
|
|
bytes /= 10;
|
|
|
|
}
|
|
|
|
return bytes %= 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *btoa(const size_t bytes, char *buf) {
|
|
|
|
|
|
|
|
char *start = buf;
|
|
|
|
|
|
|
|
int idx = -1;
|
|
|
|
|
|
|
|
size_t b = bytes;
|
|
|
|
size_t s = b;
|
|
|
|
while (1) {
|
|
|
|
if (b < 1000)
|
|
|
|
break;
|
|
|
|
s = b;
|
|
|
|
b /= 1024;
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx == -1) {
|
|
|
|
ultoa(bytes, buf, 10);
|
|
|
|
return start;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = s * 1000 / 1024;
|
|
|
|
|
|
|
|
if (s < 1024) {
|
|
|
|
b = 1024;
|
|
|
|
idx--;
|
|
|
|
}
|
|
|
|
|
|
|
|
char fd = nth_digit(s, 1);
|
|
|
|
char sd = nth_digit(s, 2);
|
|
|
|
char td = nth_digit(s, 3);
|
|
|
|
|
|
|
|
*buf = fd + '0';
|
|
|
|
buf++;
|
|
|
|
|
|
|
|
if (b < 10) {
|
|
|
|
*buf = '.';
|
|
|
|
buf++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*buf = sd + '0';
|
|
|
|
buf++;
|
|
|
|
|
|
|
|
if (b < 10)
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
if (b > 99) {
|
|
|
|
*buf = td + '0';
|
|
|
|
buf++;
|
|
|
|
}
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
|
|
|
*buf = fs_endings[idx];
|
|
|
|
buf++;
|
|
|
|
*buf = '\0';
|
|
|
|
return start;
|
|
|
|
}
|
|
|
|
|
2024-01-27 08:01:34 +00:00
|
|
|
#define UXTOA(type, name) \
|
2024-01-31 18:11:47 +00:00
|
|
|
char *name(unsigned type n, char *buffer, int radix) { \
|
|
|
|
if (n == 0) { \
|
|
|
|
buffer[0] = '0'; \
|
|
|
|
buffer[1] = '\0'; \
|
2024-02-01 21:53:07 +00:00
|
|
|
return buffer + 1; \
|
2024-01-31 18:11:47 +00:00
|
|
|
} \
|
|
|
|
char *start = buffer; \
|
|
|
|
for (; n; n /= radix) { \
|
|
|
|
*buffer++ = itoc(n % radix); \
|
|
|
|
} \
|
2024-02-01 03:30:35 +00:00
|
|
|
char *buf_end = buffer; \
|
2024-01-31 18:11:47 +00:00
|
|
|
*buffer-- = '\0'; \
|
2024-02-01 03:30:35 +00:00
|
|
|
while (buffer > start) { \
|
2024-01-31 18:11:47 +00:00
|
|
|
char tmp = *start; \
|
|
|
|
*start++ = *buffer; \
|
|
|
|
*buffer-- = tmp; \
|
|
|
|
} \
|
2024-02-01 03:30:35 +00:00
|
|
|
return buf_end; \
|
2024-01-31 18:11:47 +00:00
|
|
|
}
|
2024-01-27 08:01:34 +00:00
|
|
|
|
|
|
|
UXTOA(int, utoa)
|
|
|
|
UXTOA(long int, ultoa)
|
2024-02-01 17:48:55 +00:00
|
|
|
UXTOA(long long int, ulltoa)
|
2024-01-27 08:01:34 +00:00
|
|
|
|
|
|
|
#define XTOA(type, name) \
|
2024-02-01 03:30:35 +00:00
|
|
|
char *name(type n, char *buffer, int radix) { \
|
2024-01-31 18:11:47 +00:00
|
|
|
if (n == 0) { \
|
|
|
|
buffer[0] = '0'; \
|
|
|
|
buffer[1] = '\0'; \
|
2024-02-01 21:53:07 +00:00
|
|
|
return buffer + 1; \
|
2024-01-31 18:11:47 +00:00
|
|
|
} \
|
|
|
|
if (n < 0) { \
|
|
|
|
*buffer++ = '-'; \
|
|
|
|
n = -n; \
|
|
|
|
} \
|
|
|
|
char *start = buffer; \
|
|
|
|
for (; n; n /= radix) { \
|
|
|
|
*buffer++ = itoc(n % radix); \
|
|
|
|
} \
|
2024-02-01 03:30:35 +00:00
|
|
|
char *buf_end = buffer; \
|
2024-01-31 18:11:47 +00:00
|
|
|
*buffer-- = '\0'; \
|
2024-02-01 03:30:35 +00:00
|
|
|
while (buffer > start) { \
|
2024-01-31 18:11:47 +00:00
|
|
|
char tmp = *start; \
|
|
|
|
*start++ = *buffer; \
|
|
|
|
*buffer-- = tmp; \
|
|
|
|
} \
|
2024-02-01 03:30:35 +00:00
|
|
|
return buf_end; \
|
2024-01-31 18:11:47 +00:00
|
|
|
}
|
2024-01-27 08:01:34 +00:00
|
|
|
|
|
|
|
XTOA(int, itoa)
|
|
|
|
XTOA(long int, ltoa)
|
2024-02-01 17:48:55 +00:00
|
|
|
XTOA(long long int, lltoa)
|
2024-01-27 08:01:34 +00:00
|
|
|
|
|
|
|
#define STRTOX(name, type) \
|
2024-01-31 18:11:47 +00:00
|
|
|
type name(const char *s, char **endptr, int radix) { \
|
|
|
|
*endptr = NULL; \
|
2024-02-01 03:30:35 +00:00
|
|
|
for (; isspace(*s); s++); \
|
2024-01-31 18:11:47 +00:00
|
|
|
int neg = 0; \
|
|
|
|
switch (*s) { \
|
|
|
|
case '-': \
|
|
|
|
neg = 1; \
|
|
|
|
/* FALLTHRU */ \
|
|
|
|
case '+': \
|
|
|
|
s++; \
|
|
|
|
break; \
|
|
|
|
} \
|
|
|
|
if (!radix) { \
|
|
|
|
if (*s == '0') { \
|
|
|
|
s++; \
|
|
|
|
if (*s == 'x' || *s == 'X') { \
|
|
|
|
s++; \
|
|
|
|
radix = 16; \
|
|
|
|
} else { \
|
|
|
|
radix = 8; \
|
|
|
|
} \
|
|
|
|
} else { \
|
|
|
|
radix = 10; \
|
|
|
|
} \
|
|
|
|
} \
|
2024-02-01 03:30:35 +00:00
|
|
|
for (; *s == '0'; s++, *endptr = (void *) s); \
|
2024-01-31 18:11:47 +00:00
|
|
|
type num = 0; \
|
2024-02-01 03:30:35 +00:00
|
|
|
for (; isdigit(*s); s++, *endptr = (void *) s) { \
|
2024-01-31 18:11:47 +00:00
|
|
|
num *= radix; \
|
|
|
|
num += *s - '0'; \
|
|
|
|
} \
|
|
|
|
return num * (neg ? -1 : 1); \
|
|
|
|
}
|
2024-01-27 08:01:34 +00:00
|
|
|
|
|
|
|
STRTOX(strtoi, int)
|
|
|
|
STRTOX(strtol, long int)
|
|
|
|
STRTOX(strtoll, long long int)
|