#include "memory.h" #include #include int memcmp(const void *restrict vl, const void *restrict vr, unsigned long n) { const unsigned char *l = vl, *r = vr; for (; n && *l == *r; n--, l++, r++); return n ? *l-*r : 0; } void *memcpy(void *restrict dest, const void *restrict src, unsigned long n) { char *d = dest; const char *s = src; for (; n; n--) *d++ = *s++; return dest; } volatile void *memcpyv(volatile void *dest, const volatile void *src, unsigned long n) { volatile char *d = dest; const volatile char *s = src; for (; n; n--) *d++ = *s++; return dest; } void *memmove(void *dest, const void *src, unsigned long n) { char *d = dest; const char *s = src; if (d==s) return d; if (d -1 && c - '0' < 10; } #define ATOX(name, type) \ type name(const char *s) { \ for (; isspace(*s); s++); \ 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); \ } ATOX(atoi, int) ATOX(atol, long int) ATOX(atoll, long long int) char itoc(int i) { if (i < 10) { return '0' + i; } else { return 'a' + (i - 10); } } int ctoi(char c) { if (c < 'A') { return c - '0'; } else if (c < 'a') { return c - 'A' + 10; } else { return c - 'a' + 10; } } 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; } #define UXTOA(type, name) \ char *name(unsigned type n, char *buffer, int radix) { \ if (n == 0) { \ buffer[0] = '0'; \ buffer[1] = '\0'; \ return buffer + 1; \ } \ char *start = buffer; \ for (; n; n /= radix) { \ *buffer++ = itoc(n % radix); \ } \ char *buf_end = buffer; \ *buffer-- = '\0'; \ while (buffer > start) { \ char tmp = *start; \ *start++ = *buffer; \ *buffer-- = tmp; \ } \ return buf_end; \ } UXTOA(int, utoa) UXTOA(long int, ultoa) UXTOA(long long int, ulltoa) #define XTOA(type, name) \ char *name(type n, char *buffer, int radix) { \ if (n == 0) { \ buffer[0] = '0'; \ buffer[1] = '\0'; \ return buffer + 1; \ } \ if (n < 0) { \ *buffer++ = '-'; \ n = -n; \ } \ char *start = buffer; \ for (; n; n /= radix) { \ *buffer++ = itoc(n % radix); \ } \ char *buf_end = buffer; \ *buffer-- = '\0'; \ while (buffer > start) { \ char tmp = *start; \ *start++ = *buffer; \ *buffer-- = tmp; \ } \ return buf_end; \ } XTOA(int, itoa) XTOA(long int, ltoa) XTOA(long long int, lltoa) #define STRTOX(name, type) \ type name(const char *s, char **endptr, int radix) { \ *endptr = NULL; \ for (; isspace(*s); s++); \ 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; \ } \ } \ for (; *s == '0'; s++, *endptr = (void *) s); \ type num = 0; \ for (; isdigit(*s); s++, *endptr = (void *) s) { \ num *= radix; \ num += *s - '0'; \ } \ return num * (neg ? -1 : 1); \ } STRTOX(strtoi, int) STRTOX(strtol, long int) STRTOX(strtoll, long long int)