diff options
Diffstat (limited to 'src/ulib/stdlib.c')
| -rw-r--r-- | src/ulib/stdlib.c | 543 |
1 files changed, 0 insertions, 543 deletions
diff --git a/src/ulib/stdlib.c b/src/ulib/stdlib.c deleted file mode 100644 index 8b22b6f..0000000 --- a/src/ulib/stdlib.c +++ /dev/null @@ -1,543 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2026 Richard QIn - */ -#include "ulib/stdlib.h" -#include "ulib/string.h" -#include "ulib/ctypes.h" - -extern int sys_exit(int status); -extern void *sbrk(long increment); - -#undef errno -int errno = 0; - -#define ATEXIT_MAX 32 -static void (*__atexit_funcs[ATEXIT_MAX])(void); -static int __atexit_func_count = 0; - -int atexit(void (*function)(void)) -{ - if (__atexit_func_count >= ATEXIT_MAX) - return -1; - __atexit_funcs[__atexit_func_count++] = function; - return 0; -} - -int exit(int status) -{ - while (__atexit_func_count > 0) - { - (__atexit_funcs[--__atexit_func_count])(); - } - sys_exit(status); - - while (1) - ; - return 0; -} - -void abort(void) -{ - exit(127); -} - -char *getenv(const char *name) -{ - /* None */ - return NULL; -} - -int system(const char *command) -{ - /* None */ - return -1; -} - -/* Memory Management */ -#define ALIGNMENT 16 -#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1)) - -typedef struct header -{ - size_t size; - struct header *next; -} header_t; - -static header_t base; -static header_t *freep = NULL; - - -#define LOCK() -#define UNLOCK() - -void free(void *ptr) -{ - header_t *bp, *p; - - if (!ptr) - return; - - - bp = (header_t *)ptr - 1; - - LOCK(); - - - for (p = freep; !(bp > p && bp < p->next); p = p->next) - { - if (p >= p->next && (bp > p || bp < p->next)) - break; - } - - if ((char *)bp + bp->size == (char *)p->next) - { - bp->size += p->next->size; - bp->next = p->next->next; - } - else - { - bp->next = p->next; - } - - if ((char *)p + p->size == (char *)bp) - { - p->size += bp->size; - p->next = bp->next; - } - else - { - p->next = bp; - } - - freep = p; - UNLOCK(); -} - -static header_t *morecore(size_t nu) -{ - char *cp; - header_t *up; - - if (nu < 4096) - nu = 4096; - - nu = ALIGN(nu); - - cp = (char *)sbrk(nu); - if (cp == (void *)-1) - return NULL; - - up = (header_t *)cp; - up->size = nu; - - free((void *)(up + 1)); - return freep; -} - -void *malloc(size_t size) -{ - header_t *p, *prevp; - - if (size == 0) - return NULL; - - size = ALIGN(size + sizeof(header_t)); - - LOCK(); - - if ((prevp = freep) == NULL) - { - base.next = freep = prevp = &base; - base.size = 0; - } - - for (p = prevp->next;; prevp = p, p = p->next) - { - if (p->size >= size) - { - if (p->size == size) - { - prevp->next = p->next; - } - else - { - p->size -= size; - - p = (header_t *)((char *)p + p->size); - - p->size = size; - } - freep = prevp; - UNLOCK(); - return (void *)(p + 1); - } - - if (p == freep) - { - if ((p = morecore(size)) == NULL) - { - UNLOCK(); - errno = ENOMEM; - return NULL; - } - } - } -} - -void *calloc(size_t nmemb, size_t size) -{ - size_t total; - if (__builtin_mul_overflow(nmemb, size, &total)) - { - errno = ENOMEM; - return NULL; - } - void *p = malloc(total); - if (p) - memset(p, 0, total); - return p; -} - -void *realloc(void *ptr, size_t size) -{ - if (!ptr) - return malloc(size); - if (size == 0) - { - free(ptr); - return NULL; - } - - header_t *bp = (header_t *)ptr - 1; - size_t new_size = ALIGN(size + sizeof(header_t)); - - if (bp->size >= new_size) - return ptr; - - void *new_ptr = malloc(size); - if (!new_ptr) - return NULL; - - memcpy(new_ptr, ptr, bp->size - sizeof(header_t)); - free(ptr); - return new_ptr; -} - -/* String Conversion*/ - -unsigned long long strtoull(const char *nptr, char **endptr, int base) -{ - const char *s = nptr; - unsigned long long acc; - unsigned long long cutoff; - int c; - int neg = 0, any, cutlim; - - if (base < 0 || base == 1 || base > 36) - { - if (endptr) - *endptr = (char *)nptr; - errno = 0; /* EINVAL */ - return 0; - } - - do - { - c = *s++; - } while (isspace(c)); - - if (c == '-') - { - neg = 1; - c = *s++; - } - else if (c == '+') - { - c = *s++; - } - - if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) - { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = (c == '0' ? 8 : 10); - - cutoff = ULLONG_MAX / (unsigned long long)base; - cutlim = ULLONG_MAX % (unsigned long long)base; - - for (acc = 0, any = 0;; c = *s++) - { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - - if (c >= base) - break; - - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else - { - any = 1; - acc *= base; - acc += c; - } - } - - if (any < 0) - { - acc = ULLONG_MAX; - errno = ERANGE; - } - else if (neg) - acc = -acc; - - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - - return acc; -} - -long long strtoll(const char *nptr, char **endptr, int base) -{ - const char *s = nptr; - unsigned long long acc; - int c, neg = 0; - - do - { - c = *s++; - } while (isspace(c)); - if (c == '-') - neg = 1; - - acc = strtoull(nptr, endptr, base); - - if (errno == ERANGE && acc == ULLONG_MAX) - return neg ? LLONG_MIN : LLONG_MAX; - - if (!neg && acc > (unsigned long long)LLONG_MAX) - { - errno = ERANGE; - return LLONG_MAX; - } - if (neg && acc > (unsigned long long)LLONG_MAX + 1) - { - errno = ERANGE; - return LLONG_MIN; - } - - return neg ? -(long long)acc : (long long)acc; -} - -unsigned long strtoul(const char *nptr, char **endptr, int base) -{ - unsigned long long ret = strtoull(nptr, endptr, base); - if (ret > ULONG_MAX) - { - errno = ERANGE; - return ULONG_MAX; - } - return (unsigned long)ret; -} - -long strtol(const char *nptr, char **endptr, int base) -{ - long long ret = strtoll(nptr, endptr, base); - if (ret > LONG_MAX) - { - errno = ERANGE; - return LONG_MAX; - } - if (ret < LONG_MIN) - { - errno = ERANGE; - return LONG_MIN; - } - return (long)ret; -} - -int atoi(const char *nptr) { return (int)strtol(nptr, NULL, 10); } -long atol(const char *nptr) { return strtol(nptr, NULL, 10); } -long long atoll(const char *nptr) { return strtoll(nptr, NULL, 10); } - -double strtod(const char *nptr, char **endptr) -{ - double val = 0.0; - int sign = 1; - const char *s = nptr; - - while (isspace(*s)) - s++; - if (*s == '-') - { - sign = -1; - s++; - } - else if (*s == '+') - s++; - - while (isdigit(*s)) - { - val = val * 10.0 + (*s - '0'); - s++; - } - if (*s == '.') - { - double factor = 1.0; - s++; - while (isdigit(*s)) - { - factor *= 0.1; - val += (*s - '0') * factor; - s++; - } - } - - if (endptr) - *endptr = (char *)s; - return val * sign; -} - -double atof(const char *nptr) { return strtod(nptr, NULL); } -float strtof(const char *nptr, char **endptr) { return (float)strtod(nptr, endptr); } - -/* Sort & Search */ - -static void swap_bytes(char *a, char *b, size_t size) -{ - char temp; - while (size--) - { - temp = *a; - *a++ = *b; - *b++ = temp; - } -} - -void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) -{ - if (nmemb < 2 || size == 0) - return; - - char *base_ptr = (char *)base; - char *pivot = base_ptr + (nmemb - 1) * size; - char *i = base_ptr; - char *j = base_ptr; - - /* Partition */ - for (; j < pivot; j += size) - { - if (compar(j, pivot) < 0) - { - if (i != j) - swap_bytes(i, j, size); - i += size; - } - } - swap_bytes(i, pivot, size); - - /* Recurse */ - size_t left_count = (i - base_ptr) / size; - qsort(base, left_count, size, compar); - qsort(i + size, nmemb - left_count - 1, size, compar); -} - -void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) -{ - size_t l = 0, u = nmemb; - while (l < u) - { - size_t idx = (l + u) / 2; - const void *p = (void *)((const char *)base + (idx * size)); - int cmp = compar(key, p); - if (cmp < 0) - u = idx; - else if (cmp > 0) - l = idx + 1; - else - return (void *)p; - } - return NULL; -} - -/* Math & Mics */ - -int abs(int j) { return (j < 0) ? -j : j; } -long labs(long j) { return (j < 0) ? -j : j; } -long long llabs(long long j) { return (j < 0) ? -j : j; } - -div_t div(int numer, int denom) -{ - div_t res = {numer / denom, numer % denom}; - return res; -} -ldiv_t ldiv(long numer, long denom) -{ - ldiv_t res = {numer / denom, numer % denom}; - return res; -} -lldiv_t lldiv(long long numer, long long denom) -{ - lldiv_t res = {numer / denom, numer % denom}; - return res; -} - -static unsigned long next = 1; -int rand(void) -{ - next = next * 1103515245 + 12345; - return (unsigned int)(next / 65536) % 32768; -} -void srand(unsigned int seed) { next = seed; } - -/* Stub */ -int mblen(const char *s, size_t n) { return (s && *s && n) ? 1 : 0; } -int mbtowc(wchar_t *pwc, const char *s, size_t n) -{ - if (!s) - return 0; - if (n == 0) - return -1; - if (pwc) - *pwc = (wchar_t)*s; - return (*s != 0); -} -int wctomb(char *s, wchar_t wchar) -{ - if (!s) - return 0; - *s = (char)wchar; - return 1; -} -size_t mbstowcs(wchar_t *dest, const char *src, size_t n) -{ - size_t i = 0; - while (src[i] && i < n) - { - dest[i] = (wchar_t)src[i]; - i++; - } - if (i < n) - dest[i] = 0; - return i; -} -size_t wcstombs(char *dest, const wchar_t *src, size_t n) -{ - size_t i = 0; - while (src[i] && i < n) - { - dest[i] = (char)src[i]; - i++; - } - if (i < n) - dest[i] = 0; - return i; -}
\ No newline at end of file |
