diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 13:54:38 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 13:54:38 +0000 |
commit | 8c1ab65c0f548d20b7f177bdb736daaf603340e1 (patch) | |
tree | df55b7e75bf43f2bf500845b105afe3ac3a5157e /libc-top-half/musl/src/stdlib | |
parent | Initial commit. (diff) | |
download | wasi-libc-8c1ab65c0f548d20b7f177bdb736daaf603340e1.tar.xz wasi-libc-8c1ab65c0f548d20b7f177bdb736daaf603340e1.zip |
Adding upstream version 0.0~git20221206.8b7148f.upstream/0.0_git20221206.8b7148f
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libc-top-half/musl/src/stdlib')
22 files changed, 682 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/stdlib/abs.c b/libc-top-half/musl/src/stdlib/abs.c new file mode 100644 index 0000000..e721fdc --- /dev/null +++ b/libc-top-half/musl/src/stdlib/abs.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +int abs(int a) +{ + return a>0 ? a : -a; +} diff --git a/libc-top-half/musl/src/stdlib/atof.c b/libc-top-half/musl/src/stdlib/atof.c new file mode 100644 index 0000000..f7fcd82 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/atof.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +double atof(const char *s) +{ + return strtod(s, 0); +} diff --git a/libc-top-half/musl/src/stdlib/atoi.c b/libc-top-half/musl/src/stdlib/atoi.c new file mode 100644 index 0000000..9baca7b --- /dev/null +++ b/libc-top-half/musl/src/stdlib/atoi.c @@ -0,0 +1,16 @@ +#include <stdlib.h> +#include <ctype.h> + +int atoi(const char *s) +{ + int n=0, neg=0; + while (isspace(*s)) s++; + switch (*s) { + case '-': neg=1; + case '+': s++; + } + /* Compute n as a negative number to avoid overflow on INT_MIN */ + while (isdigit(*s)) + n = 10*n - (*s++ - '0'); + return neg ? n : -n; +} diff --git a/libc-top-half/musl/src/stdlib/atol.c b/libc-top-half/musl/src/stdlib/atol.c new file mode 100644 index 0000000..140ea3e --- /dev/null +++ b/libc-top-half/musl/src/stdlib/atol.c @@ -0,0 +1,17 @@ +#include <stdlib.h> +#include <ctype.h> + +long atol(const char *s) +{ + long n=0; + int neg=0; + while (isspace(*s)) s++; + switch (*s) { + case '-': neg=1; + case '+': s++; + } + /* Compute n as a negative number to avoid overflow on LONG_MIN */ + while (isdigit(*s)) + n = 10*n - (*s++ - '0'); + return neg ? n : -n; +} diff --git a/libc-top-half/musl/src/stdlib/atoll.c b/libc-top-half/musl/src/stdlib/atoll.c new file mode 100644 index 0000000..b693048 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/atoll.c @@ -0,0 +1,17 @@ +#include <stdlib.h> +#include <ctype.h> + +long long atoll(const char *s) +{ + long long n=0; + int neg=0; + while (isspace(*s)) s++; + switch (*s) { + case '-': neg=1; + case '+': s++; + } + /* Compute n as a negative number to avoid overflow on LLONG_MIN */ + while (isdigit(*s)) + n = 10*n - (*s++ - '0'); + return neg ? n : -n; +} diff --git a/libc-top-half/musl/src/stdlib/bsearch.c b/libc-top-half/musl/src/stdlib/bsearch.c new file mode 100644 index 0000000..fe050ea --- /dev/null +++ b/libc-top-half/musl/src/stdlib/bsearch.c @@ -0,0 +1,20 @@ +#include <stdlib.h> + +void *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *)) +{ + void *try; + int sign; + while (nel > 0) { + try = (char *)base + width*(nel/2); + sign = cmp(key, try); + if (sign < 0) { + nel /= 2; + } else if (sign > 0) { + base = (char *)try + width; + nel -= nel/2+1; + } else { + return try; + } + } + return NULL; +} diff --git a/libc-top-half/musl/src/stdlib/div.c b/libc-top-half/musl/src/stdlib/div.c new file mode 100644 index 0000000..e42c1f1 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/div.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +div_t div(int num, int den) +{ + return (div_t){ num/den, num%den }; +} diff --git a/libc-top-half/musl/src/stdlib/ecvt.c b/libc-top-half/musl/src/stdlib/ecvt.c new file mode 100644 index 0000000..797b664 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/ecvt.c @@ -0,0 +1,20 @@ +#define _GNU_SOURCE +#include <stdlib.h> +#include <stdio.h> + +char *ecvt(double x, int n, int *dp, int *sign) +{ + static char buf[16]; + char tmp[32]; + int i, j; + + if (n-1U > 15) n = 15; + sprintf(tmp, "%.*e", n-1, x); + i = *sign = (tmp[0]=='-'); + for (j=0; tmp[i]!='e'; j+=(tmp[i++]!='.')) + buf[j] = tmp[i]; + buf[j] = 0; + *dp = atoi(tmp+i+1)+1; + + return buf; +} diff --git a/libc-top-half/musl/src/stdlib/fcvt.c b/libc-top-half/musl/src/stdlib/fcvt.c new file mode 100644 index 0000000..f90928f --- /dev/null +++ b/libc-top-half/musl/src/stdlib/fcvt.c @@ -0,0 +1,25 @@ +#define _GNU_SOURCE +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +char *fcvt(double x, int n, int *dp, int *sign) +{ + char tmp[1500]; + int i, lz; + + if (n > 1400U) n = 1400; + sprintf(tmp, "%.*f", n, x); + i = (tmp[0] == '-'); + if (tmp[i] == '0') lz = strspn(tmp+i+2, "0"); + else lz = -(int)strcspn(tmp+i, "."); + + if (n<=lz) { + *sign = i; + *dp = 1; + if (n>14U) n = 14; + return "000000000000000"+14-n; + } + + return ecvt(x, n-lz, dp, sign); +} diff --git a/libc-top-half/musl/src/stdlib/gcvt.c b/libc-top-half/musl/src/stdlib/gcvt.c new file mode 100644 index 0000000..f29bc30 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/gcvt.c @@ -0,0 +1,9 @@ +#define _GNU_SOURCE +#include <stdlib.h> +#include <stdio.h> + +char *gcvt(double x, int n, char *b) +{ + sprintf(b, "%.*g", n, x); + return b; +} diff --git a/libc-top-half/musl/src/stdlib/imaxabs.c b/libc-top-half/musl/src/stdlib/imaxabs.c new file mode 100644 index 0000000..8100181 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/imaxabs.c @@ -0,0 +1,6 @@ +#include <inttypes.h> + +intmax_t imaxabs(intmax_t a) +{ + return a>0 ? a : -a; +} diff --git a/libc-top-half/musl/src/stdlib/imaxdiv.c b/libc-top-half/musl/src/stdlib/imaxdiv.c new file mode 100644 index 0000000..b2ce821 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/imaxdiv.c @@ -0,0 +1,6 @@ +#include <inttypes.h> + +imaxdiv_t imaxdiv(intmax_t num, intmax_t den) +{ + return (imaxdiv_t){ num/den, num%den }; +} diff --git a/libc-top-half/musl/src/stdlib/labs.c b/libc-top-half/musl/src/stdlib/labs.c new file mode 100644 index 0000000..83ddb14 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/labs.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +long labs(long a) +{ + return a>0 ? a : -a; +} diff --git a/libc-top-half/musl/src/stdlib/ldiv.c b/libc-top-half/musl/src/stdlib/ldiv.c new file mode 100644 index 0000000..36eb960 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/ldiv.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +ldiv_t ldiv(long num, long den) +{ + return (ldiv_t){ num/den, num%den }; +} diff --git a/libc-top-half/musl/src/stdlib/llabs.c b/libc-top-half/musl/src/stdlib/llabs.c new file mode 100644 index 0000000..9dfaf5c --- /dev/null +++ b/libc-top-half/musl/src/stdlib/llabs.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +long long llabs(long long a) +{ + return a>0 ? a : -a; +} diff --git a/libc-top-half/musl/src/stdlib/lldiv.c b/libc-top-half/musl/src/stdlib/lldiv.c new file mode 100644 index 0000000..7aaf7a0 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/lldiv.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +lldiv_t lldiv(long long num, long long den) +{ + return (lldiv_t){ num/den, num%den }; +} diff --git a/libc-top-half/musl/src/stdlib/qsort.c b/libc-top-half/musl/src/stdlib/qsort.c new file mode 100644 index 0000000..314ddc2 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/qsort.c @@ -0,0 +1,221 @@ +/* Copyright (C) 2011 by Valentin Ochs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Minor changes by Rich Felker for integration in musl, 2011-04-27. */ + +/* Smoothsort, an adaptive variant of Heapsort. Memory usage: O(1). + Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */ + +#define _BSD_SOURCE +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "atomic.h" +#define ntz(x) a_ctz_l((x)) + +typedef int (*cmpfun)(const void *, const void *, void *); + +static inline int pntz(size_t p[2]) { + int r = ntz(p[0] - 1); + if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) { + return r; + } + return 0; +} + +static void cycle(size_t width, unsigned char* ar[], int n) +{ + unsigned char tmp[256]; + size_t l; + int i; + + if(n < 2) { + return; + } + + ar[n] = tmp; + while(width) { + l = sizeof(tmp) < width ? sizeof(tmp) : width; + memcpy(ar[n], ar[0], l); + for(i = 0; i < n; i++) { + memcpy(ar[i], ar[i + 1], l); + ar[i] += l; + } + width -= l; + } +} + +/* shl() and shr() need n > 0 */ +static inline void shl(size_t p[2], int n) +{ + if(n >= 8 * sizeof(size_t)) { + n -= 8 * sizeof(size_t); + p[1] = p[0]; + p[0] = 0; + } + p[1] <<= n; + p[1] |= p[0] >> (sizeof(size_t) * 8 - n); + p[0] <<= n; +} + +static inline void shr(size_t p[2], int n) +{ + if(n >= 8 * sizeof(size_t)) { + n -= 8 * sizeof(size_t); + p[0] = p[1]; + p[1] = 0; + } + p[0] >>= n; + p[0] |= p[1] << (sizeof(size_t) * 8 - n); + p[1] >>= n; +} + +static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int pshift, size_t lp[]) +{ + unsigned char *rt, *lf; + unsigned char *ar[14 * sizeof(size_t) + 1]; + int i = 1; + + ar[0] = head; + while(pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + + if(cmp(ar[0], lf, arg) >= 0 && cmp(ar[0], rt, arg) >= 0) { + break; + } + if(cmp(lf, rt, arg) >= 0) { + ar[i++] = lf; + head = lf; + pshift -= 1; + } else { + ar[i++] = rt; + head = rt; + pshift -= 2; + } + } + cycle(width, ar, i); +} + +static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, size_t pp[2], int pshift, int trusty, size_t lp[]) +{ + unsigned char *stepson, + *rt, *lf; + size_t p[2]; + unsigned char *ar[14 * sizeof(size_t) + 1]; + int i = 1; + int trail; + + p[0] = pp[0]; + p[1] = pp[1]; + + ar[0] = head; + while(p[0] != 1 || p[1] != 0) { + stepson = head - lp[pshift]; + if(cmp(stepson, ar[0], arg) <= 0) { + break; + } + if(!trusty && pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + if(cmp(rt, stepson, arg) >= 0 || cmp(lf, stepson, arg) >= 0) { + break; + } + } + + ar[i++] = stepson; + head = stepson; + trail = pntz(p); + shr(p, trail); + pshift += trail; + trusty = 0; + } + if(!trusty) { + cycle(width, ar, i); + sift(head, width, cmp, arg, pshift, lp); + } +} + +void __qsort_r(void *base, size_t nel, size_t width, cmpfun cmp, void *arg) +{ + size_t lp[12*sizeof(size_t)]; + size_t i, size = width * nel; + unsigned char *head, *high; + size_t p[2] = {1, 0}; + int pshift = 1; + int trail; + + if (!size) return; + + head = base; + high = head + size - width; + + /* Precompute Leonardo numbers, scaled by element width */ + for(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++); + + while(head < high) { + if((p[0] & 3) == 3) { + sift(head, width, cmp, arg, pshift, lp); + shr(p, 2); + pshift += 2; + } else { + if(lp[pshift - 1] >= high - head) { + trinkle(head, width, cmp, arg, p, pshift, 0, lp); + } else { + sift(head, width, cmp, arg, pshift, lp); + } + + if(pshift == 1) { + shl(p, 1); + pshift = 0; + } else { + shl(p, pshift - 1); + pshift = 1; + } + } + + p[0] |= 1; + head += width; + } + + trinkle(head, width, cmp, arg, p, pshift, 0, lp); + + while(pshift != 1 || p[0] != 1 || p[1] != 0) { + if(pshift <= 1) { + trail = pntz(p); + shr(p, trail); + pshift += trail; + } else { + shl(p, 2); + pshift -= 2; + p[0] ^= 7; + shr(p, 1); + trinkle(head - lp[pshift] - width, width, cmp, arg, p, pshift + 1, 1, lp); + shl(p, 1); + p[0] |= 1; + trinkle(head - width, width, cmp, arg, p, pshift, 1, lp); + } + head -= width; + } +} + +weak_alias(__qsort_r, qsort_r); diff --git a/libc-top-half/musl/src/stdlib/qsort_nr.c b/libc-top-half/musl/src/stdlib/qsort_nr.c new file mode 100644 index 0000000..efe7cce --- /dev/null +++ b/libc-top-half/musl/src/stdlib/qsort_nr.c @@ -0,0 +1,14 @@ +#define _BSD_SOURCE +#include <stdlib.h> + +typedef int (*cmpfun)(const void *, const void *); + +static int wrapper_cmp(const void *v1, const void *v2, void *cmp) +{ + return ((cmpfun)cmp)(v1, v2); +} + +void qsort(void *base, size_t nel, size_t width, cmpfun cmp) +{ + __qsort_r(base, nel, width, wrapper_cmp, cmp); +} diff --git a/libc-top-half/musl/src/stdlib/strtod.c b/libc-top-half/musl/src/stdlib/strtod.c new file mode 100644 index 0000000..184bca4 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/strtod.c @@ -0,0 +1,48 @@ +#include <stdlib.h> +#ifdef __wasilibc_unmodified_upstream // Changes to optimize printf/scanf when long double isn't needed +#else +#include "printscan.h" +#define __NEED_locale_t +#include <bits/alltypes.h> +#endif +#include "shgetc.h" +#include "floatscan.h" +#include "stdio_impl.h" + +#if defined(__wasilibc_printscan_no_long_double) +static long_double strtox(const char *s, char **p, int prec) +#else +static long double strtox(const char *s, char **p, int prec) +#endif +{ + FILE f; + sh_fromstring(&f, s); + shlim(&f, 0); +#if defined(__wasilibc_printscan_no_long_double) + long_double y = __floatscan(&f, prec, 1); +#else + long double y = __floatscan(&f, prec, 1); +#endif + off_t cnt = shcnt(&f); + if (p) *p = cnt ? (char *)s + cnt : (char *)s; + return y; +} + +float strtof(const char *restrict s, char **restrict p) +{ + return strtox(s, p, 0); +} + +double strtod(const char *restrict s, char **restrict p) +{ + return strtox(s, p, 1); +} + +long double strtold(const char *restrict s, char **restrict p) +{ +#if defined(__wasilibc_printscan_no_long_double) + long_double_not_supported(); +#else + return strtox(s, p, 2); +#endif +} diff --git a/libc-top-half/musl/src/stdlib/strtol.c b/libc-top-half/musl/src/stdlib/strtol.c new file mode 100644 index 0000000..bfefea6 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/strtol.c @@ -0,0 +1,56 @@ +#include "stdio_impl.h" +#include "intscan.h" +#include "shgetc.h" +#include <inttypes.h> +#include <limits.h> +#include <ctype.h> + +static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim) +{ + FILE f; + sh_fromstring(&f, s); + shlim(&f, 0); + unsigned long long y = __intscan(&f, base, 1, lim); + if (p) { + size_t cnt = shcnt(&f); + *p = (char *)s + cnt; + } + return y; +} + +unsigned long long strtoull(const char *restrict s, char **restrict p, int base) +{ + return strtox(s, p, base, ULLONG_MAX); +} + +long long strtoll(const char *restrict s, char **restrict p, int base) +{ + return strtox(s, p, base, LLONG_MIN); +} + +unsigned long strtoul(const char *restrict s, char **restrict p, int base) +{ + return strtox(s, p, base, ULONG_MAX); +} + +long strtol(const char *restrict s, char **restrict p, int base) +{ + return strtox(s, p, base, 0UL+LONG_MIN); +} + +intmax_t strtoimax(const char *restrict s, char **restrict p, int base) +{ + return strtoll(s, p, base); +} + +uintmax_t strtoumax(const char *restrict s, char **restrict p, int base) +{ + return strtoull(s, p, base); +} + +weak_alias(strtol, __strtol_internal); +weak_alias(strtoul, __strtoul_internal); +weak_alias(strtoll, __strtoll_internal); +weak_alias(strtoull, __strtoull_internal); +weak_alias(strtoimax, __strtoimax_internal); +weak_alias(strtoumax, __strtoumax_internal); diff --git a/libc-top-half/musl/src/stdlib/wcstod.c b/libc-top-half/musl/src/stdlib/wcstod.c new file mode 100644 index 0000000..97b894e --- /dev/null +++ b/libc-top-half/musl/src/stdlib/wcstod.c @@ -0,0 +1,82 @@ +#ifdef __wasilibc_unmodified_upstream // Changes to optimize printf/scanf when long double isn't needed +#else +#include "printscan.h" +#endif +#include "shgetc.h" +#include "floatscan.h" +#include "stdio_impl.h" +#include <wchar.h> +#include <wctype.h> + +/* This read function heavily cheats. It knows: + * (1) len will always be 1 + * (2) non-ascii characters don't matter */ + +static size_t do_read(FILE *f, unsigned char *buf, size_t len) +{ + size_t i; + const wchar_t *wcs = f->cookie; + + if (!wcs[0]) wcs=L"@"; + for (i=0; i<f->buf_size && wcs[i]; i++) + f->buf[i] = wcs[i] < 128 ? wcs[i] : '@'; + f->rpos = f->buf; + f->rend = f->buf + i; + f->cookie = (void *)(wcs+i); + + if (i && len) { + *buf = *f->rpos++; + return 1; + } + return 0; +} + +#if defined(__wasilibc_printscan_no_long_double) +static long_double wcstox(const wchar_t *s, wchar_t **p, int prec) +#else +static long double wcstox(const wchar_t *s, wchar_t **p, int prec) +#endif +{ + wchar_t *t = (wchar_t *)s; + unsigned char buf[64]; + FILE f = {0}; + f.flags = 0; + f.rpos = f.rend = f.buf = buf + 4; + f.buf_size = sizeof buf - 4; +#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) + f.lock = -1; +#endif + f.read = do_read; + while (iswspace(*t)) t++; + f.cookie = (void *)t; + shlim(&f, 0); +#if defined(__wasilibc_printscan_no_long_double) + long_double y = __floatscan(&f, prec, 1); +#else + long double y = __floatscan(&f, prec, 1); +#endif + if (p) { + size_t cnt = shcnt(&f); + *p = cnt ? t + cnt : (wchar_t *)s; + } + return y; +} + +float wcstof(const wchar_t *restrict s, wchar_t **restrict p) +{ + return wcstox(s, p, 0); +} + +double wcstod(const wchar_t *restrict s, wchar_t **restrict p) +{ + return wcstox(s, p, 1); +} + +long double wcstold(const wchar_t *restrict s, wchar_t **restrict p) +{ +#if defined(__wasilibc_printscan_no_long_double) + long_double_not_supported(); +#else + return wcstox(s, p, 2); +#endif +} diff --git a/libc-top-half/musl/src/stdlib/wcstol.c b/libc-top-half/musl/src/stdlib/wcstol.c new file mode 100644 index 0000000..3aefd06 --- /dev/null +++ b/libc-top-half/musl/src/stdlib/wcstol.c @@ -0,0 +1,83 @@ +#include "stdio_impl.h" +#include "intscan.h" +#include "shgetc.h" +#include <inttypes.h> +#include <limits.h> +#include <wctype.h> +#include <wchar.h> + +/* This read function heavily cheats. It knows: + * (1) len will always be 1 + * (2) non-ascii characters don't matter */ + +static size_t do_read(FILE *f, unsigned char *buf, size_t len) +{ + size_t i; + const wchar_t *wcs = f->cookie; + + if (!wcs[0]) wcs=L"@"; + for (i=0; i<f->buf_size && wcs[i]; i++) + f->buf[i] = wcs[i] < 128 ? wcs[i] : '@'; + f->rpos = f->buf; + f->rend = f->buf + i; + f->cookie = (void *)(wcs+i); + + if (i && len) { + *buf = *f->rpos++; + return 1; + } + return 0; +} + +static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim) +{ + wchar_t *t = (wchar_t *)s; + unsigned char buf[64]; + FILE f = {0}; + f.flags = 0; + f.rpos = f.rend = f.buf = buf + 4; + f.buf_size = sizeof buf - 4; +#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) + f.lock = -1; +#endif + f.read = do_read; + while (iswspace(*t)) t++; + f.cookie = (void *)t; + shlim(&f, 0); + unsigned long long y = __intscan(&f, base, 1, lim); + if (p) { + size_t cnt = shcnt(&f); + *p = cnt ? t + cnt : (wchar_t *)s; + } + return y; +} + +unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base) +{ + return wcstox(s, p, base, ULLONG_MAX); +} + +long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base) +{ + return wcstox(s, p, base, LLONG_MIN); +} + +unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base) +{ + return wcstox(s, p, base, ULONG_MAX); +} + +long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base) +{ + return wcstox(s, p, base, 0UL+LONG_MIN); +} + +intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base) +{ + return wcstoll(s, p, base); +} + +uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base) +{ + return wcstoull(s, p, base); +} |