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;
|
---|
38 | f.rpos = f.rend = 0;
|
---|
39 | f.buf = buf + 4;
|
---|
40 | f.buf_size = sizeof buf - 4;
|
---|
41 | f.lock = -1;
|
---|
42 | f.read = do_read;
|
---|
43 | while (iswspace(*t)) t++;
|
---|
44 | f.cookie = (void *)t;
|
---|
45 | shlim(&f, 0);
|
---|
46 | unsigned long long y = __intscan(&f, base, 1, lim);
|
---|
47 | if (p) {
|
---|
48 | size_t cnt = shcnt(&f);
|
---|
49 | *p = cnt ? t + cnt : (wchar_t *)s;
|
---|
50 | }
|
---|
51 | return y;
|
---|
52 | }
|
---|
53 |
|
---|
54 | unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
---|
55 | {
|
---|
56 | return wcstox(s, p, base, ULLONG_MAX);
|
---|
57 | }
|
---|
58 |
|
---|
59 | long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
---|
60 | {
|
---|
61 | return wcstox(s, p, base, LLONG_MIN);
|
---|
62 | }
|
---|
63 |
|
---|
64 | unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
---|
65 | {
|
---|
66 | return wcstox(s, p, base, ULONG_MAX);
|
---|
67 | }
|
---|
68 |
|
---|
69 | long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
---|
70 | {
|
---|
71 | return wcstox(s, p, base, 0UL+LONG_MIN);
|
---|
72 | }
|
---|
73 |
|
---|
74 | intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
---|
75 | {
|
---|
76 | return wcstoll(s, p, base);
|
---|
77 | }
|
---|
78 |
|
---|
79 | uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
---|
80 | {
|
---|
81 | return wcstoull(s, p, base);
|
---|
82 | }
|
---|