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