mirror of https://git.musl-libc.org/git/musl
1 changed files with 61 additions and 0 deletions
@ -0,0 +1,61 @@ |
|||
#include "shgetc.h" |
|||
#include "floatscan.h" |
|||
#include "stdio_impl.h" |
|||
|
|||
/* This read function heavily cheats. It knows:
|
|||
* (1) len will always be 1 |
|||
* (2) non-ascii characters don't matter */ |
|||
|
|||
static size_t do_read(FILE *f, unsigned char *buf, size_t len) |
|||
{ |
|||
size_t i; |
|||
const wchar_t *wcs = f->cookie; |
|||
|
|||
if (!wcs[0]) wcs=L"@"; |
|||
for (i=0; i<f->buf_size && wcs[i]; i++) |
|||
f->buf[i] = wcs[i] < 128 ? wcs[i] : '@'; |
|||
f->rpos = f->buf; |
|||
f->rend = f->buf + i; |
|||
f->cookie = (void *)(wcs+i); |
|||
|
|||
if (i && len) { |
|||
*buf = *f->rpos++; |
|||
return 1; |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
static long double wcstox(const wchar_t *s, wchar_t **p, int prec) |
|||
{ |
|||
wchar_t *t = (wchar_t *)s; |
|||
unsigned char buf[64]; |
|||
FILE f = {0}; |
|||
f.flags = 0; |
|||
f.rpos = f.rend = 0; |
|||
f.buf = buf + 4; |
|||
f.buf_size = sizeof buf - 4; |
|||
f.lock = -1; |
|||
f.read = do_read; |
|||
while (iswspace(*t)) t++; |
|||
f.cookie = (void *)t; |
|||
shlim(&f, 0); |
|||
long double y = __floatscan(&f, -1, prec, 1); |
|||
off_t cnt = shcnt(&f); |
|||
if (p) *p = cnt ? t + cnt : (wchar_t *)s; |
|||
return y; |
|||
} |
|||
|
|||
float wcstof(const wchar_t *s, wchar_t **p) |
|||
{ |
|||
return wcstox(s, p, 0); |
|||
} |
|||
|
|||
double wcstod(const wchar_t *s, wchar_t **p) |
|||
{ |
|||
return wcstox(s, p, 1); |
|||
} |
|||
|
|||
long double wcstold(const wchar_t *s, wchar_t **p) |
|||
{ |
|||
return wcstox(s, p, 2); |
|||
} |
|||
Loading…
Reference in new issue