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