#include #include #include #include extern "C" { void* memcpy(void* dest, const void* src, size_t n) { for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = *((const char*)src + i); } return dest; } void* memset(void* buf, int c, size_t n) { for (size_t i = 0; i < n; ++i) { *((char*)buf + i) = (char)c; } return buf; } void* memchr(const void* buf, int c, size_t n) { const char* s = (const char*)buf; for (; n && *s != (char)c; s++, n--) ; if (n) return (void*)(const_cast(s)); return NULL; } int memcmp(const void* a, const void* b, size_t n) { if (!n) return 0; const unsigned char* ap = (const unsigned char*)a; const unsigned char* bp = (const unsigned char*)b; while (--n && *ap == *bp) { ap++; bp++; } return *ap - *bp; } void* memmove(void* dest, const void* src, size_t n) { if (dest == src) return dest; if (dest > src) for (long i = n - 1; i >= 0; i++) { *((char*)dest + i) = *((const char*)src + i); } else for (long i = 0; i < (long)n; i++) { *((char*)dest + i) = *((const char*)src + i); } return dest; } char* strdup(const char* str) { size_t len = strlen(str); char* dest = (char*)malloc(len + 1); if (!dest) return dest; return (char*)memcpy(dest, str, len + 1); } char* strndup(const char* str, size_t max) { size_t len = strnlen(str, max); char* dest = (char*)malloc(len + 1); if (!dest) return dest; memcpy(dest, str, len); dest[len] = 0; return dest; } size_t strlen(const char* str) { const char* i = str; for (; *i; ++i) ; return (i - str); } size_t strnlen(const char* str, size_t max) { char* p = (char*)memchr(str, 0, max); return p ? p - str : max; } char* strcpy(char* dest, const char* src) { return (char*)memcpy(dest, src, strlen(src) + 1); } char* strncpy(char* dest, const char* src, size_t max) { size_t i; for (i = 0; i < max && src[i] != 0; i++) dest[i] = src[i]; for (; i < max; i++) dest[i] = 0; return dest; } size_t strlcpy(char* dest, const char* src, size_t size) { size_t len = strlen(src); if (size == 0) return len; if (len < (size - 1)) { memcpy(dest, src, len); dest[len] = 0; } else { memcpy(dest, src, size - 1); dest[size - 1] = 0; } return len; } int strcmp(const char* a, const char* b) { while (*a && (*a == *b)) { a++; b++; } return *(const unsigned char*)a - *(const unsigned char*)b; } int strncmp(const char* a, const char* b, size_t max) { const char* base = a; while (*a && (*a == *b) && (size_t)(a - base) < (max - 1)) { a++; b++; } return *(const unsigned char*)a - *(const unsigned char*)b; } int strcoll(const char* a, const char* b) { return strcmp(a, b); } size_t strxfrm(char* dest, const char* src, size_t n) { strncpy(dest, src, n); return n; } size_t strcspn(const char* str, const char* reject) { const char* s = str; while (*s) { const char* rp = reject; while (*rp) { if (*s == *rp) return s - str; rp++; } s++; } return s - str; } size_t strspn(const char* str, const char* accept) { const char* s = str; while (*s) { const char* ap = accept; bool match = false; while (*ap) { if (*s == *ap) { match = true; break; } ap++; } if (!match) return s - str; s++; } return s - str; } char* strpbrk(const char* a, const char* b) { while (*a) { if (strchr(b, *a)) return const_cast(a); a++; } return NULL; } char* strcat(char* dest, const char* src) { size_t dest_len = strlen(dest); size_t i; for (i = 0; *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i); *(char*)(dest + dest_len + i) = '\0'; return dest; } char* strncat(char* dest, const char* src, size_t max) { size_t dest_len = strlen(dest); size_t i; for (i = 0; i < max && *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i); *(char*)(dest + dest_len + i) = '\0'; return dest; } char* strchr(const char* str, int c) { while (*str && *str != (char)c) str++; if (*str) return const_cast(str); return NULL; } char* strchrnul(const char* str, int c) { while (*str && *str != (char)c) str++; return const_cast(str); } char* strrchr(const char* str, int c) { const char* s = str + strlen(str); while (s != str && *s != (char)c) s--; if (s != str) return const_cast(s); if (*s == (char)c) return const_cast(s); return NULL; } char* strstr(const char* haystack, const char* needle) { size_t needle_size = strlen(needle); size_t haystack_size = strlen(haystack); while (*haystack) { if (*haystack == *needle) { if (needle_size <= haystack_size) { if (!strncmp(haystack, needle, needle_size)) return const_cast(haystack); } else { return NULL; } } haystack++; haystack_size--; } return NULL; } #pragma GCC push_options #pragma GCC diagnostic ignored "-Wwrite-strings" char* strerror(int err) { switch (err) { 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 EIO: return "Input/output error"; case E2BIG: return "Argument list too long"; case ENOEXEC: return "Exec format error"; case EBADF: return "Bad file descriptor"; case ECHILD: return "No child processes"; case EAGAIN: return "Resource temporarily unavailable"; case ENOMEM: return "Cannot allocate memory"; case EACCES: return "Permission denied"; case EFAULT: return "Bad address"; case EEXIST: return "File exists"; case ENOTDIR: return "Not a directory"; case EISDIR: return "Is a directory"; case EINVAL: return "Invalid argument"; case EMFILE: return "Too many open files"; case ENOTTY: return "Inappropriate ioctl for device"; case EFBIG: return "File too large"; case ENOSPC: return "No space left on device"; case EPIPE: return "Broken pipe"; case EDOM: return "Numerical argument out of domain"; case ERANGE: return "Numerical result out of range"; case ENOSYS: return "Function not implemented"; case ENOTSUP: return "Operation not supported"; case 0: return "Success"; default: return "Unknown error"; } } #pragma GCC pop_options char* strtok(char*, const char*) { NOT_IMPLEMENTED("strtok"); } }