| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- #include <ctype.h>
- #include <errno.h>
- #include <signal.h>
- #include <stdint.h>
- #include <stdlib.h>
- #define BYTES_PER_MAX_COPY_UNIT (sizeof(uint32_t) / sizeof(uint8_t))
- static void* _memcpy(void* _dst, const void* _src, size_t n)
- {
- void* orig_dst = _dst;
- uint8_t* dst = (uint8_t*)_dst;
- const uint8_t* src = (const uint8_t*)_src;
- for (size_t i = 0; i < n / BYTES_PER_MAX_COPY_UNIT; ++i) {
- *(uint32_t*)dst = *(uint32_t*)src;
- dst += BYTES_PER_MAX_COPY_UNIT;
- src += BYTES_PER_MAX_COPY_UNIT;
- }
- for (size_t i = 0; i < (n % BYTES_PER_MAX_COPY_UNIT); ++i) {
- *((char*)dst++) = *((char*)src++);
- }
- return orig_dst;
- }
- static void* _memset(void* _dst, int c, size_t n)
- {
- uint8_t* dst = (uint8_t*)_dst;
- c &= 0xff;
- int cc = (c + (c << 8) + (c << 16) + (c << 24));
- for (size_t i = 0; i < n / BYTES_PER_MAX_COPY_UNIT; ++i) {
- *(uint32_t*)dst = cc;
- dst += BYTES_PER_MAX_COPY_UNIT;
- }
- for (size_t i = 0; i < (n % BYTES_PER_MAX_COPY_UNIT); ++i) {
- *((char*)dst++) = c;
- }
- return dst;
- }
- static size_t _strlen(const char* str)
- {
- size_t n = 0;
- while (*(str++) != '\0')
- ++n;
- return n;
- }
- char* strchr(const char* str, int c)
- {
- const char* p = str;
- while (*p) {
- if (*p == c)
- return (char*)p;
- ++p;
- }
- return NULL;
- }
- char* strrchr(const char* str, int c)
- {
- const char* p = str + _strlen(str) - 1;
- while (p >= str) {
- if (*p == c)
- return (char*)p;
- --p;
- }
- return NULL;
- }
- char* strchrnul(const char* str, int c)
- {
- char* ret = strchr(str, c);
- if (ret)
- return ret;
- return (char*)str + _strlen(str);
- }
- char* strcpy(char* dst, const char* src)
- {
- return _memcpy(dst, src, _strlen(src) + 1);
- }
- char* strncpy(char* dst, const char* src, size_t n)
- {
- size_t len = _strlen(src);
- if (len < n) {
- _memset(dst + len, 0x00, n - len);
- _memcpy(dst, src, len);
- } else {
- _memcpy(dst, src, n);
- }
- return dst;
- }
- char* stpcpy(char* restrict dst, const char* restrict src)
- {
- return _memcpy(dst, src, _strlen(src) + 1) + _strlen(src);
- }
- char* stpncpy(char* restrict dst, const char* restrict src, size_t n)
- {
- size_t len = _strlen(src);
- if (len < n) {
- _memset(dst + len, 0x00, n - len);
- _memcpy(dst, src, len);
- } else {
- _memcpy(dst, src, n);
- }
- return dst + len;
- }
- int strncmp(const char* s1, const char* s2, size_t n)
- {
- if (n == 0)
- return 0;
- int c;
- while (n-- && (c = *s1 - *s2) == 0 && *s1) {
- ++s1;
- ++s2;
- }
- return c;
- }
- int strcmp(const char* s1, const char* s2)
- {
- return strncmp(s1, s2, __SIZE_MAX__);
- }
- int strncasecmp(const char* s1, const char* s2, size_t n)
- {
- if (n == 0)
- return 0;
- int c;
- while (n-- && (c = tolower(*s1) - tolower(*s2)) == 0 && *s1) {
- ++s1;
- ++s2;
- }
- return c;
- }
- int strcasecmp(const char* s1, const char* s2)
- {
- return strncasecmp(s1, s2, __SIZE_MAX__);
- }
- size_t strcspn(const char* str1, const char* str2)
- {
- size_t ret = 0;
- while (*str1) {
- ++ret;
- for (const char* p = str2; *p; ++p) {
- if (*str1 == *p)
- return ret;
- }
- ++str1;
- }
- return ret;
- }
- char* strstr(const char* str1, const char* str2)
- {
- const char* p = str1;
- while (*p) {
- if (*p != *str2) {
- ++p;
- continue;
- }
- const char* p1 = p;
- const char* q = str2;
- while (*q) {
- if (*p1 != *q)
- break;
- ++p1;
- ++q;
- }
- if (!*q)
- break;
- p = p1;
- }
- if (*p)
- return (char*)p;
- return NULL;
- }
- char* strpbrk(const char* str1, const char* str2)
- {
- size_t n = strcspn(str1, str2);
- if (str1[n])
- return (char*)str1 + n;
- return NULL;
- }
- char* strerror(int errnum)
- {
- switch (errnum) {
- case EPERM:
- return "Operation not permitted";
- case ENOENT:
- return "No such file or directory";
- case ESRCH:
- return "No such process";
- case EINTR:
- return "Interrupted system call";
- case EBADF:
- return "Bad file descriptor";
- case ECHILD:
- return "No child process";
- case ENOMEM:
- return "Out of memory";
- case EEXIST:
- return "File exists";
- case ENOTDIR:
- return "Not a directory";
- case EISDIR:
- return "Is a directory";
- case EINVAL:
- return "Invalid argument";
- case ENOTTY:
- return "Not a tty";
- case EPIPE:
- return "Broken pipe";
- default:
- return "No error information";
- }
- }
- char* strndup(const char* str, size_t n)
- {
- size_t len = _strlen(str);
- if (len > n)
- len = n;
- char* ret = malloc(len + 1);
- if (!ret)
- return NULL;
-
- _memcpy(ret, str, len);
- ret[len] = 0;
- return ret;
- }
- char* strdup(const char* str)
- {
- return strndup(str, __SIZE_MAX__);
- }
- char* strsignal(int sig)
- {
- switch (sig) {
- default:
- return "Unknown signal";
- case SIGINT:
- return "Interrupt";
- case SIGQUIT:
- return "Quit";
- case SIGSTOP:
- return "Stopped (signal)";
- case SIGPIPE:
- return "Broken pipe";
- }
- }
|