]>
Commit | Line | Data |
---|---|---|
320054e8 DG |
1 | #include "stdio_impl.h" |
2 | #include "intscan.h" | |
3 | #include "shgetc.h" | |
4 | #include <inttypes.h> | |
5 | #include <limits.h> | |
6 | #include <wctype.h> | |
7 | #include <wchar.h> | |
8 | ||
9 | /* This read function heavily cheats. It knows: | |
10 | * (1) len will always be 1 | |
11 | * (2) non-ascii characters don't matter */ | |
12 | ||
13 | static size_t do_read(FILE *f, unsigned char *buf, size_t len) | |
14 | { | |
15 | size_t i; | |
16 | const wchar_t *wcs = f->cookie; | |
17 | ||
18 | if (!wcs[0]) wcs=L"@"; | |
19 | for (i=0; i<f->buf_size && wcs[i]; i++) | |
20 | f->buf[i] = wcs[i] < 128 ? wcs[i] : '@'; | |
21 | f->rpos = f->buf; | |
22 | f->rend = f->buf + i; | |
23 | f->cookie = (void *)(wcs+i); | |
24 | ||
25 | if (i && len) { | |
26 | *buf = *f->rpos++; | |
27 | return 1; | |
28 | } | |
29 | return 0; | |
30 | } | |
31 | ||
32 | static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim) | |
33 | { | |
34 | wchar_t *t = (wchar_t *)s; | |
35 | unsigned char buf[64]; | |
36 | FILE f = {0}; | |
37 | f.flags = 0; | |
58795582 | 38 | f.rpos = f.rend = f.buf = buf + 4; |
320054e8 | 39 | f.buf_size = sizeof buf - 4; |
9bb4cc5c | 40 | #if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) |
320054e8 | 41 | f.lock = -1; |
9bb4cc5c | 42 | #endif |
320054e8 DG |
43 | f.read = do_read; |
44 | while (iswspace(*t)) t++; | |
45 | f.cookie = (void *)t; | |
46 | shlim(&f, 0); | |
47 | unsigned long long y = __intscan(&f, base, 1, lim); | |
48 | if (p) { | |
49 | size_t cnt = shcnt(&f); | |
50 | *p = cnt ? t + cnt : (wchar_t *)s; | |
51 | } | |
52 | return y; | |
53 | } | |
54 | ||
55 | unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base) | |
56 | { | |
57 | return wcstox(s, p, base, ULLONG_MAX); | |
58 | } | |
59 | ||
60 | long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base) | |
61 | { | |
62 | return wcstox(s, p, base, LLONG_MIN); | |
63 | } | |
64 | ||
65 | unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base) | |
66 | { | |
67 | return wcstox(s, p, base, ULONG_MAX); | |
68 | } | |
69 | ||
70 | long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base) | |
71 | { | |
72 | return wcstox(s, p, base, 0UL+LONG_MIN); | |
73 | } | |
74 | ||
75 | intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base) | |
76 | { | |
77 | return wcstoll(s, p, base); | |
78 | } | |
79 | ||
80 | uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base) | |
81 | { | |
82 | return wcstoull(s, p, base); | |
83 | } |