1570af302Sopenharmony_ci#include "stdio_impl.h" 2570af302Sopenharmony_ci#include "intscan.h" 3570af302Sopenharmony_ci#include "shgetc.h" 4570af302Sopenharmony_ci#include <inttypes.h> 5570af302Sopenharmony_ci#include <limits.h> 6570af302Sopenharmony_ci#include <wctype.h> 7570af302Sopenharmony_ci#include <wchar.h> 8570af302Sopenharmony_ci 9570af302Sopenharmony_ci/* This read function heavily cheats. It knows: 10570af302Sopenharmony_ci * (1) len will always be 1 11570af302Sopenharmony_ci * (2) non-ascii characters don't matter */ 12570af302Sopenharmony_ci 13570af302Sopenharmony_cistatic size_t do_read(FILE *f, unsigned char *buf, size_t len) 14570af302Sopenharmony_ci{ 15570af302Sopenharmony_ci size_t i; 16570af302Sopenharmony_ci const wchar_t *wcs = f->cookie; 17570af302Sopenharmony_ci 18570af302Sopenharmony_ci if (!wcs[0]) wcs=L"@"; 19570af302Sopenharmony_ci for (i=0; i<f->buf_size && wcs[i]; i++) 20570af302Sopenharmony_ci f->buf[i] = wcs[i] < 128 ? wcs[i] : '@'; 21570af302Sopenharmony_ci f->rpos = f->buf; 22570af302Sopenharmony_ci f->rend = f->buf + i; 23570af302Sopenharmony_ci f->cookie = (void *)(wcs+i); 24570af302Sopenharmony_ci 25570af302Sopenharmony_ci if (i && len) { 26570af302Sopenharmony_ci *buf = *f->rpos++; 27570af302Sopenharmony_ci return 1; 28570af302Sopenharmony_ci } 29570af302Sopenharmony_ci return 0; 30570af302Sopenharmony_ci} 31570af302Sopenharmony_ci 32570af302Sopenharmony_cistatic unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim) 33570af302Sopenharmony_ci{ 34570af302Sopenharmony_ci wchar_t *t = (wchar_t *)s; 35570af302Sopenharmony_ci unsigned char buf[64]; 36570af302Sopenharmony_ci FILE f = {0}; 37570af302Sopenharmony_ci f.flags = 0; 38570af302Sopenharmony_ci f.rpos = f.rend = f.buf = buf + 4; 39570af302Sopenharmony_ci f.buf_size = sizeof buf - 4; 40570af302Sopenharmony_ci f.lock = -1; 41570af302Sopenharmony_ci f.read = do_read; 42570af302Sopenharmony_ci while (iswspace(*t)) t++; 43570af302Sopenharmony_ci f.cookie = (void *)t; 44570af302Sopenharmony_ci shlim(&f, 0); 45570af302Sopenharmony_ci unsigned long long y = __intscan(&f, base, 1, lim); 46570af302Sopenharmony_ci if (p) { 47570af302Sopenharmony_ci size_t cnt = shcnt(&f); 48570af302Sopenharmony_ci *p = cnt ? t + cnt : (wchar_t *)s; 49570af302Sopenharmony_ci } 50570af302Sopenharmony_ci return y; 51570af302Sopenharmony_ci} 52570af302Sopenharmony_ci 53570af302Sopenharmony_ciunsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base) 54570af302Sopenharmony_ci{ 55570af302Sopenharmony_ci return wcstox(s, p, base, ULLONG_MAX); 56570af302Sopenharmony_ci} 57570af302Sopenharmony_ci 58570af302Sopenharmony_cilong long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base) 59570af302Sopenharmony_ci{ 60570af302Sopenharmony_ci return wcstox(s, p, base, LLONG_MIN); 61570af302Sopenharmony_ci} 62570af302Sopenharmony_ci 63570af302Sopenharmony_ciunsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base) 64570af302Sopenharmony_ci{ 65570af302Sopenharmony_ci return wcstox(s, p, base, ULONG_MAX); 66570af302Sopenharmony_ci} 67570af302Sopenharmony_ci 68570af302Sopenharmony_cilong wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base) 69570af302Sopenharmony_ci{ 70570af302Sopenharmony_ci return wcstox(s, p, base, 0UL+LONG_MIN); 71570af302Sopenharmony_ci} 72570af302Sopenharmony_ci 73570af302Sopenharmony_ciintmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base) 74570af302Sopenharmony_ci{ 75570af302Sopenharmony_ci return wcstoll(s, p, base); 76570af302Sopenharmony_ci} 77570af302Sopenharmony_ci 78570af302Sopenharmony_ciuintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base) 79570af302Sopenharmony_ci{ 80570af302Sopenharmony_ci return wcstoull(s, p, base); 81570af302Sopenharmony_ci} 82